diff options
author | unknown <hartmut@mysql.com> | 2005-09-30 18:16:57 +0200 |
---|---|---|
committer | unknown <hartmut@mysql.com> | 2005-09-30 18:16:57 +0200 |
commit | 7d3c939e81f8da8c9f57421864e07b4315f03f57 (patch) | |
tree | e8f6638a94b8cca6df059c2a836b5b37761c6195 | |
parent | 0585fcbe639000fa9e4210e2a4149570268f8a72 (diff) | |
parent | 39ba8376e6a3331a2c75fb3f9f5fbd6ff42f6a62 (diff) | |
download | mariadb-git-7d3c939e81f8da8c9f57421864e07b4315f03f57.tar.gz |
Merge hholzgraefe@bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/home/hartmut/projects/mysql/dev/5.0
ndb/tools/ndb_config.cpp:
Auto merged
196 files changed, 3196 insertions, 2419 deletions
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index c86687bf03b..598aaaa80ae 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -10,7 +10,7 @@ prefix_configs="--prefix=/usr/local/mysql" just_print= just_configure= full_debug= -if test ! -z $MYSQL_BUILD_PREFIX +if test -n "$MYSQL_BUILD_PREFIX" then prefix_configs="--prefix=$MYSQL_BUILD_PREFIX" fi @@ -53,8 +53,10 @@ 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" base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-openssl --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine" +base_max_no_ndb_configs="--with-innodb --with-berkeley-db --without-ndbcluster --with-archive-storage-engine --with-openssl --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine" max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-blackhole-storage-engine --with-csv-storage-engine --with-openssl --with-embedded-server --with-big-tables" max_configs="$base_max_configs --with-embedded-server" +max_no_ndb_configs="$base_max_no_ndb_configs --with-embedded-server" path=`dirname $0` . "$path/check-cpu" diff --git a/BUILD/compile-pentium-debug-max-no-ndb b/BUILD/compile-pentium-debug-max-no-ndb new file mode 100755 index 00000000000..26ec7eacc9d --- /dev/null +++ b/BUILD/compile-pentium-debug-max-no-ndb @@ -0,0 +1,11 @@ +#! /bin/sh + +path=`dirname $0` +. "$path/SETUP.sh" $@ --with-debug=full + +extra_flags="$pentium_cflags $debug_cflags $max_cflags" +c_warnings="$c_warnings $debug_extra_warnings" +cxx_warnings="$cxx_warnings $debug_extra_warnings" +extra_configs="$pentium_configs $debug_configs $max_no_ndb_configs" + +. "$path/FINISH.sh" diff --git a/BUILD/compile-ppc-debug-max-no-ndb b/BUILD/compile-ppc-debug-max-no-ndb new file mode 100755 index 00000000000..a5b922a1ec9 --- /dev/null +++ b/BUILD/compile-ppc-debug-max-no-ndb @@ -0,0 +1,11 @@ +#! /bin/sh + +path=`dirname $0` +. "$path/SETUP.sh" + +extra_flags="$ppc_cflags $debug_cflags $max_cflags" +c_warnings="$c_warnings $debug_extra_warnings" +cxx_warnings="$cxx_warnings $debug_extra_warnings" +extra_configs="$debug_configs $max_no_ndb_configs" + +. "$path/FINISH.sh" diff --git a/Makefile.am b/Makefile.am index ee0353349ea..403a4ba2137 100644 --- a/Makefile.am +++ b/Makefile.am @@ -107,15 +107,26 @@ MYSQL_TEST_RUN_ARGS = --manager-port=$(MYSQL_TEST_MANAGER_PORT) \ --master_port=$(MYSQL_TEST_MASTER_PORT) \ --slave_port=$(MYSQL_TEST_SLAVE_PORT) \ --ndbcluster_port=$(MYSQL_TEST_NDB_PORT) + test: cd mysql-test ; \ - ./mysql-test-run.pl $(MYSQL_TEST_RUN_ARGS) && \ - ./mysql-test-run.pl --ps-protocol $(MYSQL_TEST_RUN_ARGS) + ./mysql-test-run $(MYSQL_TEST_RUN_ARGS) && \ + ./mysql-test-run $(MYSQL_TEST_RUN_ARGS) --ps-protocol test-force: cd mysql-test ; \ - ./mysql-test-run --force $(MYSQL_TEST_RUN_ARGS) ; \ - ./mysql-test-run --ps-protocol --force $(MYSQL_TEST_RUN_ARGS) + ./mysql-test-run $(MYSQL_TEST_RUN_ARGS) --force ; \ + ./mysql-test-run $(MYSQL_TEST_RUN_ARGS) --ps-protocol --force + +test-pl: + cd mysql-test ; \ + ./mysql-test-run.pl $(MYSQL_TEST_RUN_ARGS) && \ + ./mysql-test-run.pl $(MYSQL_TEST_RUN_ARGS) --ps-protocol + +test-force-pl: + cd mysql-test ; \ + ./mysql-test-run.pl $(MYSQL_TEST_RUN_ARGS) --force ; \ + ./mysql-test-run.pl $(MYSQL_TEST_RUN_ARGS) --ps-protocol --force # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/client/mysql.cc b/client/mysql.cc index 05dfcbeccba..25eccbfb381 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1014,13 +1014,13 @@ static int read_and_execute(bool interactive) unsigned long clen; do { - line= my_cgets(tmpbuf.c_ptr(), tmpbuf.alloced_length(), &clen); + line= my_cgets(tmpbuf.ptr(), tmpbuf.alloced_length()-1, &clen); buffer.append(line, clen); /* if we got buffer fully filled than there is a chance that something else is still in console input buffer */ - } while (tmpbuf.alloced_length() <= clen + 1); + } while (tmpbuf.alloced_length() <= clen); line= buffer.c_ptr(); #else /* OS2 */ buffer.length(0); diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index eff05b9a8bf..5345d6d0f54 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -1434,7 +1434,7 @@ int main(int argc, char** argv) of transaction. */ fprintf(result_file, - "# End of log file\nROLLBACK;\n" + "# End of log file\nROLLBACK /* added by mysqlbinlog */;\n" "/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;\n"); if (disable_log_bin) fprintf(result_file, "/*!32316 SET SQL_LOG_BIN=@OLD_SQL_LOG_BIN*/;\n"); diff --git a/client/mysqltest.c b/client/mysqltest.c index fdc1dec6dc1..497c2de5e36 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -59,12 +59,16 @@ #include <stdarg.h> #include <sys/stat.h> #include <violite.h> -#include <regex.h> /* Our own version of lib */ +#include "my_regex.h" /* Our own version of lib */ #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif #ifndef WEXITSTATUS -# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +# ifdef __WIN__ +# define WEXITSTATUS(stat_val) (stat_val) +# else +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +# endif #endif /* MAX_QUERY is 256K -- there is a test in sp-big that is >128K */ #define MAX_QUERY (256*1024) @@ -208,7 +212,7 @@ static int got_end_timer= FALSE; static void timer_output(void); static ulonglong timer_now(void); -static regex_t ps_re; /* Holds precompiled re for valid PS statements */ +static my_regex_t ps_re; /* Holds precompiled re for valid PS statements */ static void ps_init_re(void); static int ps_match_re(char *); static char *ps_eprint(int); @@ -549,7 +553,7 @@ static void close_cons() static void close_files() { DBUG_ENTER("close_files"); - for (; cur_file != (file_stack-1) ; cur_file--) + for (; cur_file >= file_stack; cur_file--) { DBUG_PRINT("info", ("file_name: %s", cur_file->file_name)); if (cur_file->file && cur_file->file != stdin) @@ -609,7 +613,8 @@ static void die(const char *fmt, ...) if (cur_file && cur_file != file_stack) fprintf(stderr, "In included file \"%s\": ", cur_file->file_name); - fprintf(stderr, "At line %u: ", start_lineno); + if (start_lineno != 0) + fprintf(stderr, "At line %u: ", start_lineno); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); fflush(stderr); @@ -642,7 +647,9 @@ static void verbose_msg(const char *fmt, ...) va_start(args, fmt); - fprintf(stderr, "mysqltest: At line %u: ", start_lineno); + fprintf(stderr, "mysqltest: "); + if (start_lineno > 0) + fprintf(stderr, "At line %u: ", start_lineno); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); va_end(args); @@ -1097,8 +1104,8 @@ static void do_exec(struct st_query *query) (query->expected_errno[i].code.errnum == status)) { ok= 1; - verbose_msg("command \"%s\" failed with expected error: %d", - cmd, status); + DBUG_PRINT("info", ("command \"%s\" failed with expected error: %d", + cmd, status)); } } if (!ok) @@ -1383,9 +1390,7 @@ int do_sync_with_master2(long offset) int rpl_parse; if (!master_pos.file[0]) - { - die("Line %u: Calling 'sync_with_master' without calling 'save_master_pos'", start_lineno); - } + die("Calling 'sync_with_master' without calling 'save_master_pos'"); rpl_parse= mysql_rpl_parse_enabled(mysql); mysql_disable_rpl_parse(mysql); @@ -1395,14 +1400,13 @@ int do_sync_with_master2(long offset) wait_for_position: if (mysql_query(mysql, query_buf)) - die("line %u: failed in %s: %d: %s", start_lineno, query_buf, - mysql_errno(mysql), mysql_error(mysql)); + die("failed in %s: %d: %s", query_buf, mysql_errno(mysql), + mysql_error(mysql)); if (!(last_result= res= mysql_store_result(mysql))) - die("line %u: mysql_store_result() returned NULL for '%s'", start_lineno, - query_buf); + die("mysql_store_result() returned NULL for '%s'", query_buf); if (!(row= mysql_fetch_row(res))) - die("line %u: empty result in %s", start_lineno, query_buf); + die("empty result in %s", query_buf); if (!row[0]) { /* @@ -1410,10 +1414,7 @@ wait_for_position: SLAVE has been issued ? */ if (tries++ == 3) - { - die("line %u: could not sync with master ('%s' returned NULL)", - start_lineno, query_buf); - } + die("could not sync with master ('%s' returned NULL)", query_buf); sleep(1); /* So at most we will wait 3 seconds and make 4 tries */ mysql_free_result(res); goto wait_for_position; @@ -1459,10 +1460,9 @@ int do_save_master_pos() mysql_errno(mysql), mysql_error(mysql)); if (!(last_result =res = mysql_store_result(mysql))) - die("line %u: mysql_store_result() retuned NULL for '%s'", start_lineno, - query); + die("mysql_store_result() retuned NULL for '%s'", query); if (!(row = mysql_fetch_row(res))) - die("line %u: empty result in show master status", start_lineno); + die("empty result in show master status"); strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1); master_pos.pos = strtoul(row[1], (char**) 0, 10); mysql_free_result(res); last_result=0; @@ -2768,7 +2768,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), fn_format(buff, argument, "", "", 4); DBUG_ASSERT(cur_file == file_stack && cur_file->file == 0); if (!(cur_file->file= - my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME)))) + my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0)))) die("Could not open %s: errno = %d", buff, errno); cur_file->file_name= my_strdup(buff, MYF(MY_FAE)); break; @@ -2874,7 +2874,7 @@ void str_to_file(const char *fname, char *str, int size) fname=buff; } fn_format(buff,fname,"","",4); - + if ((fd = my_open(buff, O_WRONLY | O_CREAT | O_TRUNC, MYF(MY_WME | MY_FFNF))) < 0) die("Could not open %s: errno = %d", buff, errno); @@ -3767,12 +3767,13 @@ static void ps_init_re(void) "[[:space:]]*UPDATE[[:space:]]+MULTI[[:space:]]|" "[[:space:]]*INSERT[[:space:]]+SELECT[[:space:]])"; - int err= regcomp(&ps_re, ps_re_str, (REG_EXTENDED | REG_ICASE | REG_NOSUB), - &my_charset_latin1); + int err= my_regcomp(&ps_re, ps_re_str, + (REG_EXTENDED | REG_ICASE | REG_NOSUB), + &my_charset_latin1); if (err) { char erbuf[100]; - int len= regerror(err, &ps_re, erbuf, sizeof(erbuf)); + int len= my_regerror(err, &ps_re, erbuf, sizeof(erbuf)); fprintf(stderr, "error %s, %d/%d `%s'\n", ps_eprint(err), len, (int)sizeof(erbuf), erbuf); exit(1); @@ -3782,7 +3783,7 @@ static void ps_init_re(void) static int ps_match_re(char *stmt_str) { - int err= regexec(&ps_re, stmt_str, (size_t)0, NULL, 0); + int err= my_regexec(&ps_re, stmt_str, (size_t)0, NULL, 0); if (err == 0) return 1; @@ -3791,7 +3792,7 @@ static int ps_match_re(char *stmt_str) else { char erbuf[100]; - int len= regerror(err, &ps_re, erbuf, sizeof(erbuf)); + int len= my_regerror(err, &ps_re, erbuf, sizeof(erbuf)); fprintf(stderr, "error %s, %d/%d `%s'\n", ps_eprint(err), len, (int)sizeof(erbuf), erbuf); exit(1); @@ -3801,7 +3802,7 @@ static int ps_match_re(char *stmt_str) static char *ps_eprint(int err) { static char epbuf[100]; - size_t len= regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf)); + size_t len= my_regerror(REG_ITOA|err, (my_regex_t *)NULL, epbuf, sizeof(epbuf)); assert(len <= sizeof(epbuf)); return(epbuf); } @@ -3809,7 +3810,7 @@ static char *ps_eprint(int err) static void ps_free_reg(void) { - regfree(&ps_re); + my_regfree(&ps_re); } /****************************************************************************/ @@ -4304,12 +4305,20 @@ int main(int argc, char **argv) if (res_info.st_size) error|= (RESULT_CONTENT_MISMATCH | RESULT_LENGTH_MISMATCH); } - if (result_file && ds_res.length && !error) + if (ds_res.length && !error) { - if (!record) - error |= check_result(&ds_res, result_file, q->require_file); + if (result_file) + { + if (!record) + error |= check_result(&ds_res, result_file, q->require_file); + else + str_to_file(result_file, ds_res.str, ds_res.length); + } else - str_to_file(result_file, ds_res.str, ds_res.length); + { + /* Print the result to stdout */ + printf("%s", ds_res.str); + } } dynstr_free(&ds_res); diff --git a/cmd-line-utils/readline/complete.c b/cmd-line-utils/readline/complete.c index 2196c66a54c..5879100e0a6 100644 --- a/cmd-line-utils/readline/complete.c +++ b/cmd-line-utils/readline/complete.c @@ -25,6 +25,7 @@ #include <sys/types.h> #include <fcntl.h> + #if defined (HAVE_SYS_FILE_H) # include <sys/file.h> #endif @@ -1149,7 +1150,8 @@ compute_lcd_of_matches (match_list, matches, text) rl_completion_found_quote && rl_filename_quoting_desired) { - dtext = (*rl_filename_dequoting_function) (text, rl_completion_quote_character); + dtext = (*rl_filename_dequoting_function) + ((char*) text, rl_completion_quote_character); text = dtext; } diff --git a/config/ac-macros/yassl.m4 b/config/ac-macros/yassl.m4 index 7af39db48be..972e4530dab 100644 --- a/config/ac-macros/yassl.m4 +++ b/config/ac-macros/yassl.m4 @@ -23,13 +23,14 @@ AC_DEFUN([MYSQL_CHECK_YASSL], [ # System specific checks yassl_integer_extra_cxxflags="" - case $SYSTEM_TYPE--$CXX_VERSION in - sparc*solaris*--*Sun*C++*5.6*) + case $host_cpu--$CXX_VERSION in + sparc*--*Sun*C++*5.6*) # Disable inlining when compiling taocrypt/src/integer.cpp yassl_integer_extra_cxxflags="+d" + AC_MSG_NOTICE([disabling inlining for yassl/taocrypt/src/integer.cpp]) ;; esac - AC_SUBST([yassl_integer_extra_cxxflags]) + AC_SUBST([yassl_integer_extra_cxxflags]) else yassl_dir="" diff --git a/configure.in b/configure.in index 7fec0d7a637..92ce66849ac 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.14-rc) +AM_INIT_AUTOMAKE(mysql, 5.0.15-rc) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -18,7 +18,7 @@ SHARED_LIB_VERSION=15:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=14 +NDB_VERSION_BUILD=15 NDB_VERSION_STATUS="rc" # Set all version vars based on $VERSION. How do we do this more elegant ? diff --git a/dbug/my_main.c b/dbug/my_main.c index ed1c9329235..31c15aa67aa 100644 --- a/dbug/my_main.c +++ b/dbug/my_main.c @@ -8,6 +8,7 @@ #endif #include <my_global.h> /* This includes dbug.h */ +#include <my_pthread.h> int main (argc, argv) int argc; diff --git a/extra/yassl/mySTL/vector.hpp b/extra/yassl/mySTL/vector.hpp index e7f63c37c7c..9eab91cfda8 100644 --- a/extra/yassl/mySTL/vector.hpp +++ b/extra/yassl/mySTL/vector.hpp @@ -45,7 +45,8 @@ struct vector_base { vector_base() : start_(0), finish_(0), end_of_storage_(0) {} vector_base(size_t n) { - start_ = static_cast<T*>(malloc(n * sizeof(T))); + // Don't allow malloc(0), if n is 0 use 1 + start_ = static_cast<T*>(malloc((n ? n : 1) * sizeof(T))); if (!start_) abort(); finish_ = start_; end_of_storage_ = start_ + n; diff --git a/extra/yassl/taocrypt/include/hmac.hpp b/extra/yassl/taocrypt/include/hmac.hpp index 543366afc3a..cf029812ce2 100644 --- a/extra/yassl/taocrypt/include/hmac.hpp +++ b/extra/yassl/taocrypt/include/hmac.hpp @@ -56,12 +56,12 @@ private: T mac_; // MSVC 6 HACK, gives compiler error if calculated in array - enum { BSIZE = T::BLOCK_SIZE / sizeof(word32), - DSIZE = T::DIGEST_SIZE / sizeof(word32) }; + enum { HMAC_BSIZE = T::BLOCK_SIZE / sizeof(word32), + HMAC_DSIZE = T::DIGEST_SIZE / sizeof(word32) }; - word32 ip_[BSIZE]; // align ipad_ on word32 - word32 op_[BSIZE]; // align opad_ on word32 - word32 innerH_[DSIZE]; // align innerHash_ on word32 + word32 ip_[HMAC_BSIZE]; // align ipad_ on word32 + word32 op_[HMAC_BSIZE]; // align opad_ on word32 + word32 innerH_[HMAC_DSIZE]; // align innerHash_ on word32 void KeyInnerHash(); diff --git a/include/my_global.h b/include/my_global.h index 48dd165dba1..b32a8fe6baa 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -238,7 +238,7 @@ C_MODE_END /* Fix a bug in gcc 2.8.0 on IRIX 6.2 */ -#if SIZEOF_LONG == 4 && defined(__LONG_MAX__) +#if SIZEOF_LONG == 4 && defined(__LONG_MAX__) && (__GNUC__ == 2 && __GNUC_MINOR__ == 8) #undef __LONG_MAX__ /* Is a longlong value in gcc 2.8.0 ??? */ #define __LONG_MAX__ 2147483647 #endif diff --git a/include/my_sys.h b/include/my_sys.h index e21af78fcaa..422bd171eb5 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -262,6 +262,7 @@ extern char wild_many,wild_one,wild_prefix; extern const char *charsets_dir; extern char *defaults_extra_file; extern const char *defaults_group_suffix; +extern const char *defaults_file; extern my_bool timed_mutexes; @@ -280,7 +281,7 @@ enum loglevel { enum cache_type { - READ_CACHE,WRITE_CACHE, + TYPE_NOT_SET= 0, READ_CACHE, WRITE_CACHE, SEQ_READ_APPEND /* sequential read or append */, READ_FIFO, READ_NET,WRITE_NET}; diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c index aa3aef7f97c..3a3b64dd51b 100644 --- a/innobase/buf/buf0buf.c +++ b/innobase/buf/buf0buf.c @@ -321,7 +321,9 @@ buf_page_is_corrupted( fprintf(stderr, " InnoDB: Error: page %lu log sequence number %lu %lu\n" "InnoDB: is in the future! Current system log sequence number %lu %lu.\n" -"InnoDB: Your database may be corrupt.\n", +"InnoDB: Your database may be corrupt or you may have copied the InnoDB\n" +"InnoDB: tablespace but not the InnoDB log files. See\n" +"http://dev.mysql.com/doc/mysql/en/backing-up.html for more information.\n", (ulong) mach_read_from_4(read_buf + FIL_PAGE_OFFSET), (ulong) ut_dulint_get_high( mach_read_from_8(read_buf + FIL_PAGE_LSN)), diff --git a/innobase/include/mem0mem.h b/innobase/include/mem0mem.h index 87afdb8f91c..3768e93c03e 100644 --- a/innobase/include/mem0mem.h +++ b/innobase/include/mem0mem.h @@ -99,8 +99,7 @@ heap freeing. */ /********************************************************************* NOTE: Use the corresponding macros instead of this function. Creates a memory heap which allocates memory from dynamic space. For debugging -purposes, takes also the file name and line as argument in the debug -version. */ +purposes, takes also the file name and line as argument. */ UNIV_INLINE mem_heap_t* mem_heap_create_func( diff --git a/innobase/include/mem0mem.ic b/innobase/include/mem0mem.ic index 8c87c884d78..28562f7c9f8 100644 --- a/innobase/include/mem0mem.ic +++ b/innobase/include/mem0mem.ic @@ -371,8 +371,7 @@ mem_heap_free_top( /********************************************************************* NOTE: Use the corresponding macros instead of this function. Creates a memory heap which allocates memory from dynamic space. For debugging -purposes, takes also the file name and line as argument in the debug -version. */ +purposes, takes also the file name and line as argument. */ UNIV_INLINE mem_heap_t* mem_heap_create_func( diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h index 8f109a64b55..b9bbe0b5c92 100644 --- a/innobase/include/ut0mem.h +++ b/innobase/include/ut0mem.h @@ -122,6 +122,7 @@ ut_strcmp(const void* str1, const void* str2); Copies up to size - 1 characters from the NUL-terminated string src to dst, NUL-terminating the result. Returns strlen(src), so truncation occurred if the return value >= size. */ + ulint ut_strlcpy( /*=======*/ @@ -131,6 +132,18 @@ ut_strlcpy( ulint size); /* in: size of destination buffer */ /************************************************************************** +Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last +(size - 1) bytes of src, not the first. */ + +ulint +ut_strlcpy_rev( +/*===========*/ + /* out: strlen(src) */ + char* dst, /* in: destination buffer */ + const char* src, /* in: source buffer */ + ulint size); /* in: size of destination buffer */ + +/************************************************************************** Compute strlen(ut_strcpyq(str, q)). */ UNIV_INLINE ulint diff --git a/innobase/mem/mem0mem.c b/innobase/mem/mem0mem.c index 85f0119d02a..daf78008d45 100644 --- a/innobase/mem/mem0mem.c +++ b/innobase/mem/mem0mem.c @@ -187,9 +187,7 @@ mem_heap_create_block( } block->magic_n = MEM_BLOCK_MAGIC_N; - ut_memcpy(&(block->file_name), file_name + ut_strlen(file_name) - 7, - 7); - block->file_name[7]='\0'; + ut_strlcpy_rev(block->file_name, file_name, sizeof(block->file_name)); block->line = line; #ifdef MEM_PERIODIC_CHECK diff --git a/innobase/os/os0proc.c b/innobase/os/os0proc.c index 167aed93de7..24bb007e504 100644 --- a/innobase/os/os0proc.c +++ b/innobase/os/os0proc.c @@ -292,6 +292,9 @@ os_awe_allocate_physical_mem( return(TRUE); #else + UT_NOT_USED(n_megabytes); + UT_NOT_USED(page_info); + return(FALSE); #endif } @@ -349,6 +352,8 @@ os_awe_allocate_virtual_mem_window( return(ptr); #else + UT_NOT_USED(size); + return(NULL); #endif } @@ -476,6 +481,10 @@ os_awe_map_physical_mem_to_window( return(TRUE); #else + UT_NOT_USED(ptr); + UT_NOT_USED(n_mem_pages); + UT_NOT_USED(page_info); + return(FALSE); #endif } diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c index c1e3ebbf35c..47b1e24e5e1 100644 --- a/innobase/ut/ut0mem.c +++ b/innobase/ut/ut0mem.c @@ -364,7 +364,30 @@ ut_strlcpy( dst[n] = '\0'; } - return src_size; + return(src_size); +} + +/************************************************************************** +Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last +(size - 1) bytes of src, not the first. */ + +ulint +ut_strlcpy_rev( +/*===========*/ + /* out: strlen(src) */ + char* dst, /* in: destination buffer */ + const char* src, /* in: source buffer */ + ulint size) /* in: size of destination buffer */ +{ + ulint src_size = strlen(src); + + if (size != 0) { + ulint n = ut_min(src_size, size - 1); + + memcpy(dst, src + src_size - n, n + 1); + } + + return(src_size); } /************************************************************************** diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 1f5c707f538..943b75f9973 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -37,7 +37,7 @@ SUBDIRS = . examples libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \ my_time.c -sqlexamplessources = ha_example.cc ha_archive.cc ha_tina.cc +sqlexamplessources = ha_example.cc ha_tina.cc noinst_HEADERS = embedded_priv.h emb_qcache.h @@ -63,7 +63,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.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 \ - ha_blackhole.cc + ha_blackhole.cc ha_archive.cc libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) $(sqlexamplessources) libmysqld_a_SOURCES= diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 99761ceb8c7..8552b1c2b8a 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -423,9 +423,9 @@ int init_embedded_server(int argc, char **argv, char **groups) acl_error= 0; #ifndef NO_EMBEDDED_ACCESS_CHECKS - if (!(acl_error= acl_init((THD *)0, opt_noacl)) && + if (!(acl_error= acl_init(opt_noacl)) && !opt_noacl) - (void) grant_init((THD *)0); + (void) grant_init(); #endif if (acl_error || my_tz_init((THD *)0, default_tz_name, opt_bootstrap)) { @@ -514,8 +514,8 @@ void *create_embedded_thd(int client_flag, char *db) thd->db= db; thd->db_length= db ? strip_sp(db) : 0; #ifndef NO_EMBEDDED_ACCESS_CHECKS - thd->db_access= DB_ACLS; - thd->master_access= ~NO_ACCESS; + thd->security_ctx->db_access= DB_ACLS; + thd->security_ctx->master_access= ~NO_ACCESS; #endif thd->net.query_cache_query= 0; @@ -542,26 +542,27 @@ int check_embedded_connection(MYSQL *mysql) int check_embedded_connection(MYSQL *mysql) { THD *thd= (THD*)mysql->thd; + Security_context *sctx= thd->security_ctx; int result; char scramble_buff[SCRAMBLE_LENGTH]; int passwd_len; if (mysql->options.client_ip) { - thd->host= my_strdup(mysql->options.client_ip, MYF(0)); - thd->ip= my_strdup(thd->host, MYF(0)); + sctx->host= my_strdup(mysql->options.client_ip, MYF(0)); + sctx->ip= my_strdup(sctx->host, MYF(0)); } else - thd->host= (char*)my_localhost; - thd->host_or_ip= thd->host; + sctx->host= (char*)my_localhost; + sctx->host_or_ip= sctx->host; - if (acl_check_host(thd->host,thd->ip)) + if (acl_check_host(sctx->host, sctx->ip)) { result= ER_HOST_NOT_PRIVILEGED; goto err; } - thd->user= my_strdup(mysql->user, MYF(0)); + sctx->user= my_strdup(mysql->user, MYF(0)); if (mysql->passwd && mysql->passwd[0]) { memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c index c18984c7584..19f0ef77136 100644 --- a/myisam/ft_boolean_search.c +++ b/myisam/ft_boolean_search.c @@ -473,7 +473,8 @@ static int _ftb_check_phrase(const byte *s0, const byte *e0, for (;;) { n_word= (FT_WORD *)phrase_element->data; - if (my_strnncoll(cs, h_word.pos, h_word.len, n_word->pos, n_word->len)) + if (my_strnncoll(cs, (const uchar *) h_word.pos, h_word.len, + (const uchar *) n_word->pos, n_word->len)) break; if (! (phrase_element= phrase_element->next)) DBUG_RETURN(1); diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 79fafd0cf5b..074a1b23686 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1092,7 +1092,7 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend) "Keypointers and record positions doesn't match"); error=1; } - else if (param->glob_crc != info->s->state.checksum && + else if (param->glob_crc != info->state->checksum && (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))) { @@ -1388,7 +1388,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, info->state->data_file_length=sort_param.max_pos; } if (param->testflag & T_CALC_CHECKSUM) - share->state.checksum=param->glob_crc; + info->state->checksum=param->glob_crc; if (!(param->testflag & T_SILENT)) { @@ -2156,7 +2156,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, my_errno); } if (param->testflag & T_CALC_CHECKSUM) - share->state.checksum=param->glob_crc; + info->state->checksum=param->glob_crc; if (my_chsize(share->kfile,info->state->key_file_length,0,MYF(0))) mi_check_print_warning(param, @@ -2577,7 +2577,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, my_errno); } if (param->testflag & T_CALC_CHECKSUM) - share->state.checksum=param->glob_crc; + info->state->checksum=param->glob_crc; if (my_chsize(share->kfile,info->state->key_file_length,0,MYF(0))) mi_check_print_warning(param, @@ -3808,7 +3808,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename) (*org_info)->s->state.create_time=share.state.create_time; (*org_info)->s->state.unique=(*org_info)->this_unique= share.state.unique; - (*org_info)->s->state.checksum=share.state.checksum; + (*org_info)->state->checksum=info.state->checksum; (*org_info)->state->del=info.state->del; (*org_info)->s->state.dellink=share.state.dellink; (*org_info)->state->empty=info.state->empty; diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c index 60a07254e82..62ca7f8ff61 100644 --- a/myisam/mi_delete.c +++ b/myisam/mi_delete.c @@ -93,7 +93,7 @@ int mi_delete(MI_INFO *info,const byte *record) if ((*share->delete_record)(info)) goto err; /* Remove record from database */ - info->s->state.checksum-=info->checksum; + info->state->checksum-=info->checksum; info->update= HA_STATE_CHANGED+HA_STATE_DELETED+HA_STATE_ROW_CHANGED; info->state->records--; diff --git a/myisam/mi_delete_all.c b/myisam/mi_delete_all.c index 3033249886f..a30abb95070 100644 --- a/myisam/mi_delete_all.c +++ b/myisam/mi_delete_all.c @@ -41,7 +41,7 @@ int mi_delete_all_rows(MI_INFO *info) info->state->key_file_length=share->base.keystart; info->state->data_file_length=0; info->state->empty=info->state->key_empty=0; - state->checksum=0; + info->state->checksum=0; for (i=share->base.max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; ) state->key_del[i]= HA_OFFSET_ERROR; diff --git a/myisam/mi_key.c b/myisam/mi_key.c index ae50900a190..4cabfc91197 100644 --- a/myisam/mi_key.c +++ b/myisam/mi_key.c @@ -358,7 +358,7 @@ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr, byte *blob_ptr; DBUG_ENTER("_mi_put_key_in_record"); - blob_ptr= info->lastkey2; /* Place to put blob parts */ + blob_ptr= (byte*) info->lastkey2; /* Place to put blob parts */ key=(byte*) info->lastkey; /* KEy that was read */ key_end=key+info->lastkey_length; for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++) diff --git a/myisam/mi_open.c b/myisam/mi_open.c index 82663e0c318..955d55cf765 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -199,7 +199,8 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) DBUG_PRINT("warning",("saved_base_info_length: %d base_info_length: %d", len,MI_BASE_INFO_SIZE)) } - disk_pos=my_n_base_info_read((uchar*) disk_cache + base_pos, &share->base); + disk_pos= (char*) + my_n_base_info_read((uchar*) disk_cache + base_pos, &share->base); share->state.state_length=base_pos; if (!(open_flags & HA_OPEN_FOR_REPAIR) && @@ -822,7 +823,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite) mi_sizestore(ptr,state->state.empty); ptr +=8; mi_sizestore(ptr,state->state.key_empty); ptr +=8; mi_int8store(ptr,state->auto_increment); ptr +=8; - mi_int8store(ptr,(ulonglong) state->checksum);ptr +=8; + mi_int8store(ptr,(ulonglong) state->state.checksum);ptr +=8; mi_int4store(ptr,state->process); ptr +=4; mi_int4store(ptr,state->unique); ptr +=4; mi_int4store(ptr,state->status); ptr +=4; @@ -863,7 +864,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite) } -char *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state) +uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state) { uint i,keys,key_parts,key_blocks; memcpy_fixed(&state->header,ptr, sizeof(state->header)); @@ -884,7 +885,7 @@ char *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state) state->state.empty = mi_sizekorr(ptr); ptr +=8; state->state.key_empty= mi_sizekorr(ptr); ptr +=8; state->auto_increment=mi_uint8korr(ptr); ptr +=8; - state->checksum=(ha_checksum) mi_uint8korr(ptr); ptr +=8; + state->state.checksum=(ha_checksum) mi_uint8korr(ptr); ptr +=8; state->process= mi_uint4korr(ptr); ptr +=4; state->unique = mi_uint4korr(ptr); ptr +=4; state->status = mi_uint4korr(ptr); ptr +=4; @@ -974,7 +975,7 @@ uint mi_base_info_write(File file, MI_BASE_INFO *base) } -char *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base) +uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base) { base->keystart = mi_sizekorr(ptr); ptr +=8; base->max_data_file_length = mi_sizekorr(ptr); ptr +=8; diff --git a/myisam/mi_test1.c b/myisam/mi_test1.c index 5727c699469..60225ccc7f3 100644 --- a/myisam/mi_test1.c +++ b/myisam/mi_test1.c @@ -237,7 +237,7 @@ static int run_test(const char *filename) pos=HA_OFFSET_ERROR; } if (found != row_count) - printf("Found %ld of %ld rows\n", found,row_count); + printf("Found %ld of %ld rows\n", (ulong) found, (ulong) row_count); } if (!silent) @@ -303,7 +303,8 @@ static int run_test(const char *filename) if ((error=mi_rrnd(file,read_record,i == 1 ? 0L : HA_OFFSET_ERROR)) == -1) { if (found != row_count-deleted) - printf("Found only %ld of %ld rows\n",found,row_count-deleted); + printf("Found only %ld of %ld rows\n", (ulong) found, + (ulong) (row_count - deleted)); break; } if (!error) diff --git a/myisam/mi_update.c b/myisam/mi_update.c index ab23f2e6da9..86652996afe 100644 --- a/myisam/mi_update.c +++ b/myisam/mi_update.c @@ -162,7 +162,7 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec) if (auto_key_changed) update_auto_increment(info,newrec); if (share->calc_checksum) - share->state.checksum+=(info->checksum - old_checksum); + info->state->checksum+=(info->checksum - old_checksum); info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_AKTIV | key_changed); diff --git a/myisam/mi_write.c b/myisam/mi_write.c index c8f9aa84a41..8785adae9a2 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -142,7 +142,7 @@ int mi_write(MI_INFO *info, byte *record) { if ((*share->write_record)(info,record)) goto err; - share->state.checksum+=info->checksum; + info->state->checksum+=info->checksum; } if (share->base.auto_key) update_auto_increment(info,record); diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 4fc0e560911..a90495e5fcb 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -705,7 +705,7 @@ get_one_option(int optid, fprintf(stderr, "Invalid value of stats_method: %s.\n", argument); exit(1); } - check_param.stats_method= method-1; + check_param.stats_method= (enum_mi_stats_method) (method-1); break; } #ifdef DEBUG /* Only useful if debugging */ @@ -1261,7 +1261,7 @@ static void descript(MI_CHECK *param, register MI_INFO *info, my_string name) share->base.raid_chunksize); } if (share->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) - printf("Checksum: %23s\n",llstr(info->s->state.checksum,llbuff)); + printf("Checksum: %23s\n",llstr(info->state->checksum,llbuff)); ; if (share->options & HA_OPTION_DELAY_KEY_WRITE) printf("Keys are only flushed at close\n"); @@ -1576,7 +1576,7 @@ static int mi_sort_records(MI_CHECK *param, old_record_count=info->state->records; info->state->records=0; if (sort_info.new_data_file_type != COMPRESSED_RECORD) - share->state.checksum=0; + info->state->checksum=0; if (sort_record_index(&sort_param,info,keyinfo,share->state.key_root[sort_key], temp_buff, sort_key,new_file,update_index) || diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 6b040f2ef0e..87a1b757d88 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -38,6 +38,7 @@ typedef struct st_mi_status_info my_off_t key_empty; /* lost space in indexfile */ my_off_t key_file_length; my_off_t data_file_length; + ha_checksum checksum; } MI_STATUS_INFO; typedef struct st_mi_state_info @@ -75,7 +76,6 @@ typedef struct st_mi_state_info ulong sec_index_changed; /* Updated when new sec_index */ ulong sec_index_used; /* which extra index are in use */ ulonglong key_map; /* Which keys are in use */ - ha_checksum checksum; ulong version; /* timestamp of create */ time_t create_time; /* Time when created database */ time_t recover_time; /* Time for last recover */ @@ -680,10 +680,10 @@ extern uint read_pack_length(uint version, const uchar *buf, ulong *length); extern uint calc_pack_length(uint version, ulong length); uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite); -char *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state); +uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state); uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead); uint mi_base_info_write(File file, MI_BASE_INFO *base); -char *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base); +uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base); int mi_keyseg_write(File file, const HA_KEYSEG *keyseg); char *mi_keyseg_read(char *ptr, HA_KEYSEG *keyseg); uint mi_keydef_write(File file, MI_KEYDEF *keydef); diff --git a/myisam/myisampack.c b/myisam/myisampack.c index 3b091cd6ea2..114e80d8f1a 100644 --- a/myisam/myisampack.c +++ b/myisam/myisampack.c @@ -2008,7 +2008,7 @@ static char *hexdigits(ulonglong value) static int write_header(PACK_MRG_INFO *mrg,uint head_length,uint trees, my_off_t tot_elements,my_off_t filelength) { - byte *buff=file_buffer.pos; + byte *buff= (byte*) file_buffer.pos; bzero(buff,HEAD_LENGTH); memcpy_fixed(buff,myisam_pack_file_magic,4); @@ -2024,7 +2024,7 @@ static int write_header(PACK_MRG_INFO *mrg,uint head_length,uint trees, if (test_only) return 0; VOID(my_seek(file_buffer.file,0L,MY_SEEK_SET,MYF(0))); - return my_write(file_buffer.file,file_buffer.pos,HEAD_LENGTH, + return my_write(file_buffer.file,(const byte *) file_buffer.pos,HEAD_LENGTH, MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL)) != 0; } @@ -2472,7 +2472,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts) { if (flush_buffer((ulong) max_calc_length + (ulong) max_pack_length)) break; - record_pos=file_buffer.pos; + record_pos= (byte*) file_buffer.pos; file_buffer.pos+=max_pack_length; for (start_pos=record, count= huff_counts; count < end_count ; count++) { @@ -2795,7 +2795,8 @@ static char *make_old_name(char *new_name, char *old_name) static void init_file_buffer(File file, pbool read_buffer) { file_buffer.file=file; - file_buffer.buffer=my_malloc(ALIGN_SIZE(RECORD_CACHE_SIZE),MYF(MY_WME)); + file_buffer.buffer= (uchar*) my_malloc(ALIGN_SIZE(RECORD_CACHE_SIZE), + MYF(MY_WME)); file_buffer.end=file_buffer.buffer+ALIGN_SIZE(RECORD_CACHE_SIZE)-8; file_buffer.pos_in_file=0; error_on_write=0; @@ -2837,7 +2838,8 @@ static int flush_buffer(ulong neaded_length) file_buffer.pos_in_file+=length; if (test_only) return 0; - if (error_on_write|| my_write(file_buffer.file,file_buffer.buffer, + if (error_on_write|| my_write(file_buffer.file, + (const byte*) file_buffer.buffer, length, MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL))) { @@ -2850,13 +2852,13 @@ static int flush_buffer(ulong neaded_length) { char *tmp; neaded_length+=256; /* some margin */ - tmp=my_realloc(file_buffer.buffer, neaded_length,MYF(MY_WME)); + tmp= my_realloc((char*) file_buffer.buffer, neaded_length,MYF(MY_WME)); if (!tmp) return 1; file_buffer.pos= ((uchar*) tmp + (ulong) (file_buffer.pos - file_buffer.buffer)); - file_buffer.buffer=tmp; - file_buffer.end=tmp+neaded_length-8; + file_buffer.buffer= (uchar*) tmp; + file_buffer.end= (uchar*) (tmp+neaded_length-8); } return 0; } @@ -2965,7 +2967,7 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length, share->state.key_root[key]= HA_OFFSET_ERROR; for (key=0 ; key < share->state.header.max_block_size ; key++) share->state.key_del[key]= HA_OFFSET_ERROR; - share->state.checksum=crc; /* Save crc here */ + isam_file->state->checksum=crc; /* Save crc here */ share->changed=1; /* Force write of header */ share->state.open_count=0; share->global_changed=0; @@ -3001,7 +3003,7 @@ static int save_state_mrg(File file,PACK_MRG_INFO *mrg,my_off_t new_length, state.dellink= HA_OFFSET_ERROR; state.version=(ulong) time((time_t*) 0); mi_clear_all_keys_active(state.key_map); - state.checksum=crc; + state.state.checksum=crc; if (isam_file->s->base.keys) isamchk_neaded=1; state.changed=STATE_CHANGED | STATE_NOT_ANALYZED; /* Force check of table */ diff --git a/myisam/sp_key.c b/myisam/sp_key.c index 1d43f89cba9..77cecdc0931 100644 --- a/myisam/sp_key.c +++ b/myisam/sp_key.c @@ -142,7 +142,7 @@ static int sp_add_point_to_mbr(uchar *(*wkb), uchar *end, uint n_dims, { if ((*wkb) > end - 8) return -1; - get_double(&ord, *wkb); + get_double(&ord, (const byte*) *wkb); (*wkb)+= 8; if (ord < *mbr) float8store((char*) mbr, ord); diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index 5149d322f7f..0fb4282ce7f 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -680,7 +680,8 @@ sub mtr_mysqladmin_shutdown { mtr_add_arg($args, "shutdown"); # We don't wait for termination of mysqladmin my $pid= mtr_spawn($::exe_mysqladmin, $args, - "", $::path_manager_log, $::path_manager_log, ""); + "", $::path_manager_log, $::path_manager_log, "", + { append_log_file => 1 }); $mysql_admin_pids{$pid}= 1; } diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index 9002f204602..515988ee5c7 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -257,11 +257,11 @@ sub mtr_print_header () { print "\n"; if ( $::opt_timer ) { - print "TEST RESULT TIME (ms)\n"; + print "TEST RESULT TIME (ms)\n"; } else { - print "TEST RESULT\n"; + print "TEST RESULT\n"; } mtr_print_line(); print "\n"; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 47c0e8f4e41..b93a2d08262 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2,37 +2,35 @@ # -*- cperl -*- # This is a transformation of the "mysql-test-run" Bourne shell script -# to Perl. This is just an intermediate step, the goal is to rewrite -# the Perl script to C. The complexity of the mysql-test-run script -# makes it a bit hard to write and debug it as a C program directly, -# so this is considered a prototype. +# to Perl. There are reasons this rewrite is not the prettiest Perl +# you have seen # -# Because of this the Perl coding style may in some cases look a bit -# funny. The rules used are +# - The original script is huge and for most part uncommented, +# not even a usage description of the flags. # -# - The coding style is as close as possible to the C/C++ MySQL -# coding standard. +# - There has been an attempt to write a replacement in C for the +# original Bourne shell script. It was kind of working but lacked +# lot of functionality to really be a replacement. Not to redo +# that mistake and catch all the obscure features of the original +# script, the rewrite in Perl is more close to the original script +# meaning it also share some of the ugly parts as well. # -# - Where NULL is to be returned, the undefined value is used. +# - The original intention was that this script was to be a prototype +# to be the base for a new C version with full functionality. Since +# then it was decided that the Perl version should replace the +# Bourne shell version, but the Perl style still reflects the wish +# to make the Perl to C step easy. # -# - Regexp comparisons are simple and can be translated to strcmp -# and other string functions. To ease this transformation matching -# is done in the lib "lib/mtr_match.pl", i.e. regular expressions -# should be avoided in the main program. +# Some coding style from the original intent has been kept # -# - The "unless" construct is not to be used. It is the same as "if !". -# -# - opendir/readdir/closedir is used instead of glob()/<*>. +# - To make this Perl script easy to alter even for those that not +# code Perl that often, the coding style is as close as possible to +# the C/C++ MySQL coding standard. # # - All lists of arguments to send to commands are Perl lists/arrays, # not strings we append args to. Within reason, most string # concatenation for arguments should be avoided. # -# - sprintf() is to be used, within reason, for all string creation. -# This mtr_add_arg() function is also based on sprintf(), i.e. you -# use a format string and put the variable argument in the argument -# list. -# # - Functions defined in the main program are not to be prefixed, # functions in "library files" are to be prefixed with "mtr_" (for # Mysql-Test-Run). There are some exceptions, code that fits best in @@ -476,6 +474,7 @@ sub command_line_setup () { # Read the command line # Note: Keep list, and the order, in sync with usage at end of this file + Getopt::Long::Configure("pass_through"); GetOptions( # Control what engine/variation to run 'embedded-server' => \$opt_embedded_server, @@ -566,7 +565,21 @@ sub command_line_setup () { usage(""); } - @opt_cases= @ARGV; + foreach my $arg ( @ARGV ) + { + if ( $arg =~ /^--skip-/ ) + { + push(@opt_extra_mysqld_opt, $arg); + } + elsif ( $arg =~ /^-/ ) + { + usage("Invalid option \"$arg\""); + } + else + { + push(@opt_cases, $arg); + } + } # -------------------------------------------------------------------------- # Set the "var/" directory, as it is the base for everything else @@ -658,11 +671,6 @@ sub command_line_setup () { mtr_error("Coverage test needs the source - please use source dist"); } - if ( $glob_use_embedded_server and ! $opt_source_dist ) - { - mtr_error("Embedded server needs source tree - please use source dist"); - } - if ( $opt_gdb ) { $opt_wait_timeout= 300; @@ -755,78 +763,96 @@ sub command_line_setup () { # Put this into a hash, will be a C struct - $master->[0]->{'path_myddir'}= "$opt_vardir/master-data"; - $master->[0]->{'path_myerr'}= "$opt_vardir/log/master.err"; - $master->[0]->{'path_mylog'}= "$opt_vardir/log/master.log"; - $master->[0]->{'path_mypid'}= "$opt_vardir/run/master.pid"; - $master->[0]->{'path_mysock'}= "$opt_tmpdir/master.sock"; - $master->[0]->{'path_myport'}= $opt_master_myport; - $master->[0]->{'start_timeout'}= 400; # enough time create innodb tables - - $master->[0]->{'ndbcluster'}= 1; # ndbcluster not started - - $master->[1]->{'path_myddir'}= "$opt_vardir/master1-data"; - $master->[1]->{'path_myerr'}= "$opt_vardir/log/master1.err"; - $master->[1]->{'path_mylog'}= "$opt_vardir/log/master1.log"; - $master->[1]->{'path_mypid'}= "$opt_vardir/run/master1.pid"; - $master->[1]->{'path_mysock'}= "$opt_tmpdir/master1.sock"; - $master->[1]->{'path_myport'}= $opt_master_myport + 1; - $master->[1]->{'start_timeout'}= 400; # enough time create innodb tables - - $slave->[0]->{'path_myddir'}= "$opt_vardir/slave-data"; - $slave->[0]->{'path_myerr'}= "$opt_vardir/log/slave.err"; - $slave->[0]->{'path_mylog'}= "$opt_vardir/log/slave.log"; - $slave->[0]->{'path_mypid'}= "$opt_vardir/run/slave.pid"; - $slave->[0]->{'path_mysock'}= "$opt_tmpdir/slave.sock"; - $slave->[0]->{'path_myport'}= $opt_slave_myport; - $slave->[0]->{'start_timeout'}= 400; - - $slave->[1]->{'path_myddir'}= "$opt_vardir/slave1-data"; - $slave->[1]->{'path_myerr'}= "$opt_vardir/log/slave1.err"; - $slave->[1]->{'path_mylog'}= "$opt_vardir/log/slave1.log"; - $slave->[1]->{'path_mypid'}= "$opt_vardir/run/slave1.pid"; - $slave->[1]->{'path_mysock'}= "$opt_tmpdir/slave1.sock"; - $slave->[1]->{'path_myport'}= $opt_slave_myport + 1; - $slave->[1]->{'start_timeout'}= 300; - - $slave->[2]->{'path_myddir'}= "$opt_vardir/slave2-data"; - $slave->[2]->{'path_myerr'}= "$opt_vardir/log/slave2.err"; - $slave->[2]->{'path_mylog'}= "$opt_vardir/log/slave2.log"; - $slave->[2]->{'path_mypid'}= "$opt_vardir/run/slave2.pid"; - $slave->[2]->{'path_mysock'}= "$opt_tmpdir/slave2.sock"; - $slave->[2]->{'path_myport'}= $opt_slave_myport + 2; - $slave->[2]->{'start_timeout'}= 300; - - $instance_manager->{'path_err'}= "$opt_vardir/log/im.err"; - $instance_manager->{'path_log'}= "$opt_vardir/log/im.log"; - $instance_manager->{'path_pid'}= "$opt_vardir/run/im.pid"; - $instance_manager->{'path_sock'}= "$opt_tmpdir/im.sock"; - $instance_manager->{'port'}= $im_port; - $instance_manager->{'start_timeout'}= $master->[0]->{'start_timeout'}; - $instance_manager->{'admin_login'}= 'im_admin'; - $instance_manager->{'admin_password'}= 'im_admin_secret'; - $instance_manager->{'admin_sha1'}= '*598D51AD2DFF7792045D6DF3DDF9AA1AF737B295'; - $instance_manager->{'password_file'}= "$opt_vardir/im.passwd"; - $instance_manager->{'defaults_file'}= "$opt_vardir/im.cnf"; - - $instance_manager->{'instances'}->[0]->{'server_id'}= 1; - $instance_manager->{'instances'}->[0]->{'port'}= $im_mysqld1_port; - $instance_manager->{'instances'}->[0]->{'path_datadir'}= - "$opt_vardir/im_mysqld_1.data"; - $instance_manager->{'instances'}->[0]->{'path_sock'}= - "$opt_vardir/mysqld_1.sock"; - $instance_manager->{'instances'}->[0]->{'path_pid'}= - "$opt_vardir/mysqld_1.pid"; - - $instance_manager->{'instances'}->[1]->{'server_id'}= 2; - $instance_manager->{'instances'}->[1]->{'port'}= $im_mysqld2_port; - $instance_manager->{'instances'}->[1]->{'path_datadir'}= - "$opt_vardir/im_mysqld_2.data"; - $instance_manager->{'instances'}->[1]->{'path_sock'}= - "$opt_vardir/mysqld_2.sock"; - $instance_manager->{'instances'}->[1]->{'path_pid'}= - "$opt_vardir/mysqld_2.pid"; - $instance_manager->{'instances'}->[1]->{'nonguarded'}= 1; + $master->[0]= + { + path_myddir => "$opt_vardir/master-data", + path_myerr => "$opt_vardir/log/master.err", + path_mylog => "$opt_vardir/log/master.log", + path_mypid => "$opt_vardir/run/master.pid", + path_mysock => "$opt_tmpdir/master.sock", + path_myport => $opt_master_myport, + start_timeout => 400, # enough time create innodb tables + + ndbcluster => 1, # ndbcluster not started + }; + + $master->[1]= + { + path_myddir => "$opt_vardir/master1-data", + path_myerr => "$opt_vardir/log/master1.err", + path_mylog => "$opt_vardir/log/master1.log", + path_mypid => "$opt_vardir/run/master1.pid", + path_mysock => "$opt_tmpdir/master1.sock", + path_myport => $opt_master_myport + 1, + start_timeout => 400, # enough time create innodb tables + }; + + $slave->[0]= + { + path_myddir => "$opt_vardir/slave-data", + path_myerr => "$opt_vardir/log/slave.err", + path_mylog => "$opt_vardir/log/slave.log", + path_mypid => "$opt_vardir/run/slave.pid", + path_mysock => "$opt_tmpdir/slave.sock", + path_myport => $opt_slave_myport, + start_timeout => 400, + }; + + $slave->[1]= + { + path_myddir => "$opt_vardir/slave1-data", + path_myerr => "$opt_vardir/log/slave1.err", + path_mylog => "$opt_vardir/log/slave1.log", + path_mypid => "$opt_vardir/run/slave1.pid", + path_mysock => "$opt_tmpdir/slave1.sock", + path_myport => $opt_slave_myport + 1, + start_timeout => 300, + }; + + $slave->[2]= + { + path_myddir => "$opt_vardir/slave2-data", + path_myerr => "$opt_vardir/log/slave2.err", + path_mylog => "$opt_vardir/log/slave2.log", + path_mypid => "$opt_vardir/run/slave2.pid", + path_mysock => "$opt_tmpdir/slave2.sock", + path_myport => $opt_slave_myport + 2, + start_timeout => 300, + }; + + $instance_manager= + { + path_err => "$opt_vardir/log/im.err", + path_log => "$opt_vardir/log/im.log", + path_pid => "$opt_vardir/run/im.pid", + path_sock => "$opt_tmpdir/im.sock", + port => $im_port, + start_timeout => $master->[0]->{'start_timeout'}, + admin_login => 'im_admin', + admin_password => 'im_admin_secret', + admin_sha1 => '*598D51AD2DFF7792045D6DF3DDF9AA1AF737B295', + password_file => "$opt_vardir/im.passwd", + defaults_file => "$opt_vardir/im.cnf", + }; + + $instance_manager->{'instances'}->[0]= + { + server_id => 1, + port => $im_mysqld1_port, + path_datadir => "$opt_vardir/im_mysqld_1.data", + path_sock => "$opt_vardir/mysqld_1.sock", + path_pid => "$opt_vardir/mysqld_1.pid", + }; + + $instance_manager->{'instances'}->[1]= + { + server_id => 2, + port => $im_mysqld2_port, + path_datadir => "$opt_vardir/im_mysqld_2.data", + path_sock => "$opt_vardir/mysqld_2.sock", + path_pid => "$opt_vardir/mysqld_2.pid", + nonguarded => 1, + }; if ( $opt_extern ) { @@ -871,7 +897,7 @@ sub executable_setup () { if ( $glob_use_embedded_server ) { my $path_examples= "$glob_basedir/libmysqld/examples"; - $exe_mysqltest= mtr_exe_exists("$path_examples/mysqltest"); + $exe_mysqltest= mtr_exe_exists("$path_examples/mysqltest_embedded"); $exe_mysql_client_test= mtr_exe_exists("$path_examples/mysql_client_test_embedded", "/usr/bin/false"); @@ -898,7 +924,6 @@ sub executable_setup () { else { $path_client_bindir= mtr_path_exists("$glob_basedir/bin"); - $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest"); $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump"); $exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow"); $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog"); @@ -2137,7 +2162,8 @@ sub mysqld_start ($$$$) { { if ( $pid= mtr_spawn($exe, $args, "", $master->[$idx]->{'path_myerr'}, - $master->[$idx]->{'path_myerr'}, "", + $master->[$idx]->{'path_myerr'}, + "", { append_log_file => 1 }) ) { return sleep_until_file_created($master->[$idx]->{'path_mypid'}, @@ -2149,7 +2175,8 @@ sub mysqld_start ($$$$) { { if ( $pid= mtr_spawn($exe, $args, "", $slave->[$idx]->{'path_myerr'}, - $slave->[$idx]->{'path_myerr'}, "", + $slave->[$idx]->{'path_myerr'}, + "", { append_log_file => 1 }) ) { return sleep_until_file_created($slave->[$idx]->{'path_mypid'}, @@ -2492,7 +2519,7 @@ sub run_mysqltest ($) { $ENV{'MYSQL_TEST'}= "$exe_mysqltest " . join(" ", @$args); # ---------------------------------------------------------------------- - # Add args that should not go into the MYSQL_TEST environment var + # Add arguments that should not go into the MYSQL_TEST env var # ---------------------------------------------------------------------- mtr_add_arg($args, "-R"); diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result index d525b019c64..2bba44d36e9 100644 --- a/mysql-test/r/bdb.result +++ b/mysql-test/r/bdb.result @@ -1429,10 +1429,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range v v 13 NULL # Using where explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL # Using where +1 SIMPLE t1 ref v v 13 const # Using where explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL # Using where +1 SIMPLE t1 ref v v 13 const # Using where alter table t1 add unique(v); ERROR 23000: Duplicate entry '{ ' for key 1 alter table t1 add key(v); @@ -1622,10 +1622,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range v v 258 NULL # Using where explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 258 NULL # Using where +1 SIMPLE t1 ref v v 258 const # Using where explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 258 NULL # Using where +1 SIMPLE t1 ref v v 258 const # Using where explain select * from t1 where v='a'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 258 const # Using where @@ -1702,10 +1702,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range v v 33 NULL # Using where explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 33 NULL # Using where +1 SIMPLE t1 ref v v 33 const # Using where explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 33 NULL # Using where +1 SIMPLE t1 ref v v 33 const # Using where explain select * from t1 where v='a'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 33 const # Using where diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result index b02f85132aa..ea80695ad7b 100644 --- a/mysql-test/r/case.result +++ b/mysql-test/r/case.result @@ -103,8 +103,8 @@ t1 CREATE TABLE `t1` ( `c2` varchar(1) character set latin1 collate latin1_danish_ci NOT NULL default '', `c3` varbinary(1) NOT NULL default '', `c4` varbinary(1) NOT NULL default '', - `c5` varbinary(4) NOT NULL default '', - `c6` varbinary(4) NOT NULL default '', + `c5` varbinary(3) NOT NULL default '', + `c6` varbinary(3) NOT NULL default '', `c7` decimal(2,1) NOT NULL default '0.0', `c8` decimal(2,1) NOT NULL default '0.0', `c9` decimal(2,1) default NULL, @@ -152,11 +152,11 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `COALESCE(1)` int(1) NOT NULL default '0', - `COALESCE(1.0)` decimal(2,1) NOT NULL default '0.0', + `COALESCE(1.0)` decimal(2,1) unsigned NOT NULL default '0.0', `COALESCE('a')` varchar(1) NOT NULL default '', `COALESCE(1,1.0)` decimal(2,1) NOT NULL default '0.0', `COALESCE(1,'1')` varbinary(1) NOT NULL default '', - `COALESCE(1.1,'1')` varbinary(4) NOT NULL default '', + `COALESCE(1.1,'1')` varbinary(3) NOT NULL default '', `COALESCE('a' COLLATE latin1_bin,'b')` varchar(1) character set latin1 collate latin1_bin NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result index 1b5bdf98afd..fa8e810cf2b 100644 --- a/mysql-test/r/cast.result +++ b/mysql-test/r/cast.result @@ -74,6 +74,18 @@ CAST(DATE "2004-01-22 21:45:33" AS BINARY(4)) 2004 Warnings: Warning 1292 Truncated incorrect CHAR(4) value: '2004-01-22 21:45:33' +select CAST(0xb3 as signed); +CAST(0xb3 as signed) +179 +select CAST(0x8fffffffffffffff as signed); +CAST(0x8fffffffffffffff as signed) +-8070450532247928833 +select CAST(0xffffffffffffffff as unsigned); +CAST(0xffffffffffffffff as unsigned) +18446744073709551615 +select CAST(0xfffffffffffffffe as signed); +CAST(0xfffffffffffffffe as signed) +-2 select cast('-10a' as signed integer); cast('-10a' as signed integer) -10 diff --git a/mysql-test/r/ctype_ucs_binlog.result b/mysql-test/r/ctype_ucs_binlog.result index fd4db66f6fe..14220a7df13 100644 --- a/mysql-test/r/ctype_ucs_binlog.result +++ b/mysql-test/r/ctype_ucs_binlog.result @@ -18,6 +18,6 @@ SET @@session.sql_mode=0; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; insert into t2 values (@v); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; drop table t2; diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index 7c9d88acf90..19325731d35 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -368,3 +368,15 @@ create table t2 (a int); select * from (select * from t1,t2) foo; ERROR 42S21: Duplicate column name 'a' drop table t1,t2; +create table t1 (ID int unsigned not null auto_increment, +DATA varchar(5) not null, primary key (ID)); +create table t2 (ID int unsigned not null auto_increment, +DATA varchar(5) not null, FID int unsigned not null, +primary key (ID)); +select A.* from (t1 inner join (select * from t2) as A on t1.ID = A.FID); +ID DATA FID +select t2.* from ((select * from t1) as A inner join t2 on A.ID = t2.FID); +ID DATA FID +select t2.* from (select * from t1) as A inner join t2 on A.ID = t2.FID; +ID DATA FID +drop table t1, t2; diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result index 969cb06e9fe..7f40dfa3a36 100644 --- a/mysql-test/r/heap.result +++ b/mysql-test/r/heap.result @@ -379,10 +379,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL v NULL NULL NULL 271 Using where explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL v NULL NULL NULL 271 Using where +1 SIMPLE t1 ref v v 13 const 10 Using where explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL v NULL NULL NULL 271 Using where +1 SIMPLE t1 ref v v 13 const 10 Using where alter table t1 add unique(v); ERROR 23000: Duplicate entry '{ ' for key 1 select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a' order by length(concat('*',v,'*',c,'*',t,'*')); @@ -602,10 +602,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range v v 13 NULL # Using where explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL # Using where +1 SIMPLE t1 ref v v 13 const # Using where explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL # Using where +1 SIMPLE t1 ref v v 13 const # Using where alter table t1 add unique(v); ERROR 23000: Duplicate entry '{ ' for key 1 select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a' order by length(concat('*',v,'*',c,'*',t,'*')); diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 0d8de3a8e7d..3fcdccceed6 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1997,10 +1997,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range v v 13 NULL # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL # Using where; Using index +1 SIMPLE t1 ref v v 13 const # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL # Using where; Using index +1 SIMPLE t1 ref v v 13 const # Using where; Using index alter table t1 add unique(v); ERROR 23000: Duplicate entry '{ ' for key 1 alter table t1 add key(v); @@ -2188,10 +2188,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range v v 303 NULL # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 303 NULL # Using where; Using index +1 SIMPLE t1 ref v v 303 const # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 303 NULL # Using where; Using index +1 SIMPLE t1 ref v v 303 const # Using where; Using index explain select * from t1 where v='a'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 303 const # Using where @@ -2268,10 +2268,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range v v 33 NULL # Using where explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 33 NULL # Using where +1 SIMPLE t1 ref v v 33 const # Using where explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 33 NULL # Using where +1 SIMPLE t1 ref v v 33 const # Using where explain select * from t1 where v='a'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 33 const # Using where @@ -2616,3 +2616,31 @@ SET FOREIGN_KEY_CHECKS=1; INSERT INTO t2 VALUES(3); ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`)) DROP TABLE t2; +create table test_checksum(a int not null) engine=innodb DEFAULT CHARSET=latin1; +insert into test_checksum values (1),(2); +set autocommit=0; +checksum table test_checksum; +Table Checksum +test.test_checksum 1531596814 +insert into test_checksum values(3); +checksum table test_checksum; +Table Checksum +test.test_checksum 2605035534 +commit; +checksum table test_checksum; +Table Checksum +test.test_checksum 127268899 +commit; +drop table test_checksum; +create table test_checksum(a int not null) engine=innodb DEFAULT CHARSET=latin1; +insert into test_checksum values (1),(2); +set autocommit=1; +checksum table test_checksum; +Table Checksum +test.test_checksum 1531596814 +set autocommit=1; +insert into test_checksum values(3); +checksum table test_checksum; +Table Checksum +test.test_checksum 127268899 +drop table test_checksum; diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result index f9a25898a6f..9d514be76e8 100644 --- a/mysql-test/r/join_nested.result +++ b/mysql-test/r/join_nested.result @@ -1375,3 +1375,31 @@ groupid price 6 9900 DROP VIEW v1,v2; DROP TABLE t1,t2,t3,t4; +CREATE TABLE t1(a int); +CREATE TABLE t2(b int); +CREATE TABLE t3(c int, d int); +CREATE TABLE t4(d int); +CREATE TABLE t5(e int, f int); +CREATE TABLE t6(f int); +CREATE VIEW v1 AS +SELECT e FROM t5 JOIN t6 ON t5.e=t6.f; +CREATE VIEW v2 AS +SELECT e FROM t5 NATURAL JOIN t6; +SELECT t1.a FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c JOIN t4 USING(d); +a +SELECT t1.x FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c JOIN t4 USING(d); +ERROR 42S22: Unknown column 't1.x' in 'field list' +SELECT t1.a FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c NATURAL JOIN t4; +a +SELECT t1.x FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c NATURAL JOIN t4; +ERROR 42S22: Unknown column 't1.x' in 'field list' +SELECT v1.e FROM v1 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d); +e +SELECT v1.x FROM v1 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d); +ERROR 42S22: Unknown column 'v1.x' in 'field list' +SELECT v2.e FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d); +e +SELECT v2.x FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d); +ERROR 42S22: Unknown column 'v2.x' in 'field list' +DROP VIEW v1, v2; +DROP TABLE t1, t2, t3, t4, t5, t6; diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 4ddc1fdab12..e028e58acf5 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -654,30 +654,30 @@ create table t3 engine=merge union=(t1, t2) select (select max(a) from t2); ERROR HY000: You can't specify target table 't2' for update in FROM clause drop table t1, t2; create table t1 ( -a double(16,6), +a double(14,4), b varchar(10), index (a,b) ) engine=merge union=(t2,t3); create table t2 ( -a double(16,6), +a double(14,4), b varchar(10), index (a,b) ) engine=myisam; create table t3 ( -a double(16,6), +a double(14,4), b varchar(10), index (a,b) ) engine=myisam; insert into t2 values ( null, ''); -insert into t2 values ( 9999999999.999999, ''); +insert into t2 values ( 9999999999.999, ''); insert into t3 select * from t2; select min(a), max(a) from t1; min(a) max(a) -9999999999.999998 9999999999.999998 +9999999999.9990 9999999999.9990 flush tables; select min(a), max(a) from t1; min(a) max(a) -9999999999.999998 9999999999.999998 +9999999999.9990 9999999999.9990 drop table t1, t2, t3; create table t1 (a int,b int,c int, index (a,b,c)); create table t2 (a int,b int,c int, index (a,b,c)); diff --git a/mysql-test/r/metadata.result b/mysql-test/r/metadata.result index 50b0b6ae294..0a170e16188 100644 --- a/mysql-test/r/metadata.result +++ b/mysql-test/r/metadata.result @@ -2,7 +2,7 @@ drop table if exists t1,t2; select 1, 1.0, -1, "hello", NULL; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def 1 8 1 1 N 32897 0 63 -def 1.0 246 4 3 N 129 1 63 +def 1.0 246 3 3 N 161 1 63 def -1 8 2 2 N 32897 0 63 def hello 253 5 5 N 1 31 8 def NULL 6 0 0 Y 32896 0 63 diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 0e5969ed83e..f484a937b27 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -802,10 +802,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range v v 13 NULL # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL # Using where; Using index +1 SIMPLE t1 ref v v 13 const # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 13 NULL # Using where; Using index +1 SIMPLE t1 ref v v 13 const # Using where; Using index alter table t1 add unique(v); ERROR 23000: Duplicate entry '{ ' for key 1 alter table t1 add key(v); @@ -993,10 +993,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range v v 303 NULL # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 303 NULL # Using where; Using index +1 SIMPLE t1 ref v v 303 const # Using where; Using index explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 303 NULL # Using where; Using index +1 SIMPLE t1 ref v v 303 const # Using where; Using index explain select * from t1 where v='a'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 303 const # Using where @@ -1073,10 +1073,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range v v 33 NULL # Using where explain select count(*) from t1 where v between 'a' and 'a '; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 33 NULL # Using where +1 SIMPLE t1 ref v v 33 const # Using where explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range v v 33 NULL # Using where +1 SIMPLE t1 ref v v 33 const # Using where explain select * from t1 where v='a'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref v v 33 const # Using where diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index e08d0b519b8..cab3d924dd2 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -40,7 +40,7 @@ load data LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/SQL_LOAD_MB-3-0' INTO table t1; SET TIMESTAMP=1000000000; load data LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/SQL_LOAD_MB-4-0' INTO table t1; # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- Broken LOAD DATA -- @@ -53,7 +53,7 @@ SET @@session.sql_mode=0; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; insert into t1 values ("Alas"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- --database -- @@ -62,7 +62,7 @@ ROLLBACK; ROLLBACK; SET INSERT_ID=1; # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- --position -- @@ -75,7 +75,7 @@ SET @@session.sql_mode=0; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; insert into t1 values ("Alas"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- Remote -- @@ -106,7 +106,7 @@ load data LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/SQL_LOAD_MB-3-2' INTO table t1; SET TIMESTAMP=1000000000; load data LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/SQL_LOAD_MB-4-2' INTO table t1; # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- Broken LOAD DATA -- @@ -119,7 +119,7 @@ SET @@session.sql_mode=0; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; insert into t1 values ("Alas"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- --database -- @@ -128,7 +128,7 @@ ROLLBACK; ROLLBACK; SET INSERT_ID=1; # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- --position -- @@ -141,7 +141,7 @@ SET @@session.sql_mode=0; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; insert into t1 values ("Alas"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- reading stdin -- @@ -154,7 +154,7 @@ BEGIN; SET TIMESTAMP=1108844555; insert t1 values (1); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; @@ -164,6 +164,6 @@ BEGIN; SET TIMESTAMP=1108844555; insert t1 values (1); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; drop table t1, t2; diff --git a/mysql-test/r/mysqlbinlog2.result b/mysql-test/r/mysqlbinlog2.result index 926c6f35c4b..eb5fb4a87f8 100644 --- a/mysql-test/r/mysqlbinlog2.result +++ b/mysql-test/r/mysqlbinlog2.result @@ -40,7 +40,7 @@ SET INSERT_ID=5; SET TIMESTAMP=1579609946; insert into t1 values(null, "e"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- offset -- @@ -67,7 +67,7 @@ SET INSERT_ID=5; SET TIMESTAMP=1579609946; insert into t1 values(null, "e"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- start-position -- @@ -84,7 +84,7 @@ SET INSERT_ID=5; SET TIMESTAMP=1579609946; insert into t1 values(null, "e"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- stop-position -- @@ -107,7 +107,7 @@ SET INSERT_ID=3; SET TIMESTAMP=1579609944; insert into t1 values(null, "c"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- start-datetime -- @@ -128,7 +128,7 @@ SET INSERT_ID=5; SET TIMESTAMP=1579609946; insert into t1 values(null, "e"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- stop-datetime -- @@ -148,7 +148,7 @@ SET INSERT_ID=2; SET TIMESTAMP=1579609942; insert into t1 values(null, "b"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- Local with 2 binlogs on command line -- @@ -184,7 +184,7 @@ SET @@session.sql_mode=0; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; insert into t1 values(null, "f"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- offset -- @@ -218,7 +218,7 @@ SET @@session.sql_mode=0; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; insert into t1 values(null, "f"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- start-position -- @@ -242,7 +242,7 @@ SET @@session.sql_mode=0; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; insert into t1 values(null, "f"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- stop-position -- @@ -272,7 +272,7 @@ SET TIMESTAMP=1579609946; insert into t1 values(null, "e"); SET INSERT_ID=6; # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- start-datetime -- @@ -300,7 +300,7 @@ SET @@session.sql_mode=0; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; insert into t1 values(null, "f"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- stop-datetime -- @@ -320,7 +320,7 @@ SET INSERT_ID=2; SET TIMESTAMP=1579609942; insert into t1 values(null, "b"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- Remote -- @@ -349,7 +349,7 @@ SET INSERT_ID=5; SET TIMESTAMP=1579609946; insert into t1 values(null, "e"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- offset -- @@ -376,7 +376,7 @@ SET INSERT_ID=5; SET TIMESTAMP=1579609946; insert into t1 values(null, "e"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- start-position -- @@ -393,7 +393,7 @@ SET INSERT_ID=5; SET TIMESTAMP=1579609946; insert into t1 values(null, "e"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- stop-position -- @@ -416,7 +416,7 @@ SET INSERT_ID=3; SET TIMESTAMP=1579609944; insert into t1 values(null, "c"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- start-datetime -- @@ -437,7 +437,7 @@ SET INSERT_ID=5; SET TIMESTAMP=1579609946; insert into t1 values(null, "e"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- stop-datetime -- @@ -457,7 +457,7 @@ SET INSERT_ID=2; SET TIMESTAMP=1579609942; insert into t1 values(null, "b"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- Remote with 2 binlogs on command line -- @@ -493,7 +493,7 @@ SET @@session.sql_mode=0; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; insert into t1 values(null, "f"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- offset -- @@ -527,7 +527,7 @@ SET @@session.sql_mode=0; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; insert into t1 values(null, "f"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- start-position -- @@ -551,7 +551,7 @@ SET @@session.sql_mode=0; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; insert into t1 values(null, "f"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- stop-position -- @@ -581,7 +581,7 @@ SET TIMESTAMP=1579609946; insert into t1 values(null, "e"); SET INSERT_ID=6; # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- start-datetime -- @@ -609,7 +609,7 @@ SET @@session.sql_mode=0; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; insert into t1 values(null, "f"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- stop-datetime -- @@ -629,7 +629,7 @@ SET INSERT_ID=2; SET TIMESTAMP=1579609942; insert into t1 values(null, "b"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- to-last-log -- @@ -661,7 +661,7 @@ SET INSERT_ID=6; SET TIMESTAMP=1579609943; insert into t1 values(null, "f"); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- end of test -- diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 5b75ebaab04..9bb669fd9b8 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1735,22 +1735,65 @@ create view v1 as select * from v3 where b in (1, 2, 3, 4, 5, 6, 7); create view v2 as select v3.a from v3, v1 where v1.a=v3.a and v3.b=3 limit 1; -drop view v1, v2, v3; -drop table t1; -show full tables; -Tables_in_test Table_type -t1 BASE TABLE -v1 VIEW -v2 VIEW -v3 VIEW -show create view v1; -View Create View -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `v3`.`a` AS `a`,`v3`.`b` AS `b`,`v3`.`c` AS `c` from `v3` where (`v3`.`b` in (1,2,3,4,5,6,7)) -select * from v1; -a b c -1 2 one -2 4 two -3 6 three + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( + `a` int(11) default NULL, + `b` int(11) default NULL, + `c` varchar(30) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + + +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +LOCK TABLES `t1` WRITE; +INSERT INTO `t1` VALUES (1,2,'one'),(2,4,'two'),(3,6,'three'); +UNLOCK TABLES; +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +DROP TABLE IF EXISTS `v1`; +/*!50001 DROP VIEW IF EXISTS `v1`*/; +/*!50001 CREATE TABLE `v1` ( + `a` int(11) default NULL, + `b` int(11) default NULL, + `c` varchar(30) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1*/; +DROP TABLE IF EXISTS `v2`; +/*!50001 DROP VIEW IF EXISTS `v2`*/; +/*!50001 CREATE TABLE `v2` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1*/; +DROP TABLE IF EXISTS `v3`; +/*!50001 DROP VIEW IF EXISTS `v3`*/; +/*!50001 CREATE TABLE `v3` ( + `a` int(11) default NULL, + `b` int(11) default NULL, + `c` varchar(30) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1*/; +/*!50001 DROP TABLE IF EXISTS `v1`*/; +/*!50001 DROP VIEW IF EXISTS `v1`*/; +/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `v3`.`a` AS `a`,`v3`.`b` AS `b`,`v3`.`c` AS `c` from `v3` where (`v3`.`b` in (1,2,3,4,5,6,7))*/; +/*!50001 DROP TABLE IF EXISTS `v2`*/; +/*!50001 DROP VIEW IF EXISTS `v2`*/; +/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `v3`.`a` AS `a` from (`v3` join `v1`) where ((`v1`.`a` = `v3`.`a`) and (`v3`.`b` = 3)) limit 1*/; +/*!50001 DROP TABLE IF EXISTS `v3`*/; +/*!50001 DROP VIEW IF EXISTS `v3`*/; +/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b`,`t1`.`c` AS `c` from `t1`*/; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + drop view v1, v2, v3; drop table t1; CREATE TABLE t1 (a int, b bigint default NULL); diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index c643a5ae647..7c01b7bdfba 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -180,6 +180,7 @@ source database echo message echo message mysqltest: At line 1: Empty variable +mysqltest: At line 1: command "false" failed mysqltest: At line 1: Missing argument in exec MySQL "MySQL" @@ -301,6 +302,7 @@ mysqltest: At line 1: First argument to dec must be a variable (start with $) mysqltest: At line 1: End of line junk detected: "1000" mysqltest: At line 1: Missing arguments to system, nothing to do! mysqltest: At line 1: Missing arguments to system, nothing to do! +mysqltest: At line 1: system command 'false' failed test test2 test3 @@ -344,6 +346,10 @@ mysqltest: At line 1: Wrong column number to replace_column in 'replace_column 1 mysqltest: At line 1: Invalid integer argument "10!" mysqltest: At line 1: End of line junk detected: "!" mysqltest: At line 1: Invalid integer argument "a" +Output from mysqltest-x.inc +Output from mysqltest-x.inc +Output from mysqltest-x.inc +mysqltest: Could not open ./non_existing_file.inc: errno = 2 failing_statement; 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 'failing_statement' at line 1 failing_statement; diff --git a/mysql-test/r/ndb_config.result b/mysql-test/r/ndb_config.result index c2557f85c0b..629d37f1e5e 100644 --- a/mysql-test/r/ndb_config.result +++ b/mysql-test/r/ndb_config.result @@ -3,3 +3,5 @@ ndbd,1,localhost ndbd,2,localhost ndb_mgmd,3,localhost mysqld,4, mysqld,5, mysql 1 localhost 41943040 12582912 2 localhost 41943040 12582912 1 2 +ndbd,1,localhost ndbd,2,localhost ndb_mgmd,3,localhost mysqld,4, mysqld,5, mysqld,6, mysqld,7, +ndbd,1,localhost,52428800,26214400 ndbd,2,localhost,52428800,36700160 ndbd,3,localhost,52428800,52428800 ndbd,4,localhost,52428800,52428800 ndb_mgmd,5,localhost,, mysqld,6,localhost,, diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index 16ead200933..c839c8a65b9 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -1775,7 +1775,7 @@ Table Create Table t5 CREATE TABLE `t5` ( `const01` bigint(1) NOT NULL default '0', `param01` bigint(20) default NULL, - `const02` decimal(2,1) NOT NULL default '0.0', + `const02` decimal(2,1) unsigned NOT NULL default '0.0', `param02` decimal(65,30) default NULL, `const03` double NOT NULL default '0', `param03` double default NULL, @@ -1805,7 +1805,7 @@ select * from t5 ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def test t5 t5 const01 const01 8 1 1 N 32769 0 63 def test t5 t5 param01 param01 8 20 1 Y 32768 0 63 -def test t5 t5 const02 const02 246 4 3 N 1 1 63 +def test t5 t5 const02 const02 246 3 3 N 33 1 63 def test t5 t5 param02 param02 246 67 32 Y 0 30 63 def test t5 t5 const03 const03 5 17 1 N 32769 31 63 def test t5 t5 param03 param03 5 23 1 Y 32768 31 63 diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index 9ab5a79f755..81d6180e41f 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -1758,7 +1758,7 @@ Table Create Table t5 CREATE TABLE `t5` ( `const01` bigint(1) NOT NULL default '0', `param01` bigint(20) default NULL, - `const02` decimal(2,1) NOT NULL default '0.0', + `const02` decimal(2,1) unsigned NOT NULL default '0.0', `param02` decimal(65,30) default NULL, `const03` double NOT NULL default '0', `param03` double default NULL, @@ -1788,7 +1788,7 @@ select * from t5 ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def test t5 t5 const01 const01 8 1 1 N 32769 0 63 def test t5 t5 param01 param01 8 20 1 Y 32768 0 63 -def test t5 t5 const02 const02 246 4 3 N 1 1 63 +def test t5 t5 const02 const02 246 3 3 N 33 1 63 def test t5 t5 param02 param02 246 67 32 Y 0 30 63 def test t5 t5 const03 const03 5 17 1 N 32769 31 63 def test t5 t5 param03 param03 5 23 1 Y 32768 31 63 diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index 8336a5bf99b..931e6b7c86c 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -1759,7 +1759,7 @@ Table Create Table t5 CREATE TABLE `t5` ( `const01` bigint(1) NOT NULL default '0', `param01` bigint(20) default NULL, - `const02` decimal(2,1) NOT NULL default '0.0', + `const02` decimal(2,1) unsigned NOT NULL default '0.0', `param02` decimal(65,30) default NULL, `const03` double NOT NULL default '0', `param03` double default NULL, @@ -1789,7 +1789,7 @@ select * from t5 ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def test t5 t5 const01 const01 8 1 1 N 32769 0 63 def test t5 t5 param01 param01 8 20 1 Y 32768 0 63 -def test t5 t5 const02 const02 246 4 3 N 1 1 63 +def test t5 t5 const02 const02 246 3 3 N 33 1 63 def test t5 t5 param02 param02 246 67 32 Y 0 30 63 def test t5 t5 const03 const03 5 17 1 N 32769 31 63 def test t5 t5 param03 param03 5 23 1 Y 32768 31 63 diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index f341247a417..3b9244c251f 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -1695,7 +1695,7 @@ Table Create Table t5 CREATE TABLE `t5` ( `const01` bigint(1) NOT NULL default '0', `param01` bigint(20) default NULL, - `const02` decimal(2,1) NOT NULL default '0.0', + `const02` decimal(2,1) unsigned NOT NULL default '0.0', `param02` decimal(65,30) default NULL, `const03` double NOT NULL default '0', `param03` double default NULL, @@ -1725,7 +1725,7 @@ select * from t5 ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def test t5 t5 const01 const01 8 1 1 N 32769 0 63 def test t5 t5 param01 param01 8 20 1 Y 32768 0 63 -def test t5 t5 const02 const02 246 4 3 N 1 1 63 +def test t5 t5 const02 const02 246 3 3 N 33 1 63 def test t5 t5 param02 param02 246 67 32 Y 0 30 63 def test t5 t5 const03 const03 5 17 1 N 32769 31 63 def test t5 t5 param03 param03 5 23 1 Y 32768 31 63 @@ -4707,7 +4707,7 @@ Table Create Table t5 CREATE TABLE `t5` ( `const01` bigint(1) NOT NULL default '0', `param01` bigint(20) default NULL, - `const02` decimal(2,1) NOT NULL default '0.0', + `const02` decimal(2,1) unsigned NOT NULL default '0.0', `param02` decimal(65,30) default NULL, `const03` double NOT NULL default '0', `param03` double default NULL, @@ -4737,7 +4737,7 @@ select * from t5 ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def test t5 t5 const01 const01 8 1 1 N 32769 0 63 def test t5 t5 param01 param01 8 20 1 Y 32768 0 63 -def test t5 t5 const02 const02 246 4 3 N 1 1 63 +def test t5 t5 const02 const02 246 3 3 N 33 1 63 def test t5 t5 param02 param02 246 67 32 Y 0 30 63 def test t5 t5 const03 const03 5 17 1 N 32769 31 63 def test t5 t5 param03 param03 5 23 1 Y 32768 31 63 diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result index fe4536827e6..643e12f7e2d 100644 --- a/mysql-test/r/ps_6bdb.result +++ b/mysql-test/r/ps_6bdb.result @@ -1758,7 +1758,7 @@ Table Create Table t5 CREATE TABLE `t5` ( `const01` bigint(1) NOT NULL default '0', `param01` bigint(20) default NULL, - `const02` decimal(2,1) NOT NULL default '0.0', + `const02` decimal(2,1) unsigned NOT NULL default '0.0', `param02` decimal(65,30) default NULL, `const03` double NOT NULL default '0', `param03` double default NULL, @@ -1788,7 +1788,7 @@ select * from t5 ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def test t5 t5 const01 const01 8 1 1 N 32769 0 63 def test t5 t5 param01 param01 8 20 1 Y 32768 0 63 -def test t5 t5 const02 const02 246 4 3 N 1 1 63 +def test t5 t5 const02 const02 246 3 3 N 33 1 63 def test t5 t5 param02 param02 246 67 32 Y 0 30 63 def test t5 t5 const03 const03 5 17 1 N 32769 31 63 def test t5 t5 param03 param03 5 23 1 Y 32768 31 63 diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result index c4cb92bdc02..9fbe67f581b 100644 --- a/mysql-test/r/ps_7ndb.result +++ b/mysql-test/r/ps_7ndb.result @@ -1758,7 +1758,7 @@ Table Create Table t5 CREATE TABLE `t5` ( `const01` bigint(1) NOT NULL default '0', `param01` bigint(20) default NULL, - `const02` decimal(2,1) NOT NULL default '0.0', + `const02` decimal(2,1) unsigned NOT NULL default '0.0', `param02` decimal(65,30) default NULL, `const03` double NOT NULL default '0', `param03` double default NULL, @@ -1788,7 +1788,7 @@ select * from t5 ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def test t5 t5 const01 const01 8 1 1 N 32769 0 63 def test t5 t5 param01 param01 8 20 1 Y 32768 0 63 -def test t5 t5 const02 const02 246 4 3 N 1 1 63 +def test t5 t5 const02 const02 246 3 3 N 33 1 63 def test t5 t5 param02 param02 246 67 32 Y 0 30 63 def test t5 t5 const03 const03 5 17 1 N 32769 31 63 def test t5 t5 param03 param03 5 23 1 Y 32768 31 63 diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index 6adbea973df..69c150fc0b7 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -1,4 +1,4 @@ -drop table if exists t1, t2; +drop table if exists t1, t2, t3; CREATE TABLE t1 ( event_date date DEFAULT '0000-00-00' NOT NULL, type int(11) DEFAULT '0' NOT NULL, @@ -787,3 +787,26 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index drop view v1; drop table t1; +create table t3 (a int); +insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (a varchar(10), filler char(200), key(a)) charset=binary; +insert into t1 values ('a',''); +insert into t1 values ('a ',''); +insert into t1 values ('a ', ''); +insert into t1 select concat('a', 1000 + A.a + 10 * (B.a + 10 * C.a)), '' + from t3 A, t3 B, t3 C; +create table t2 (a varchar(10), filler char(200), key(a)); +insert into t2 select * from t1; +explain select * from t1 where a between 'a' and 'a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 13 NULL # Using where +explain select * from t1 where a = 'a' or a='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 13 NULL # Using where +explain select * from t2 where a between 'a' and 'a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref a a 13 const # Using where +explain select * from t2 where a = 'a' or a='a '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref a a 13 const # Using where +drop table t1,t2,t3; diff --git a/mysql-test/r/rpl_charset.result b/mysql-test/r/rpl_charset.result index 26403952bb9..28f694a3933 100644 --- a/mysql-test/r/rpl_charset.result +++ b/mysql-test/r/rpl_charset.result @@ -247,7 +247,7 @@ SET TIMESTAMP=1000000000; SET @@session.character_set_client=7,@@session.collation_connection=51,@@session.collation_server=30; INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ'); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; drop table t1; create table `t1` ( diff --git a/mysql-test/r/rpl_timezone.result b/mysql-test/r/rpl_timezone.result index 9cfe793b9ba..64d05aa787e 100644 --- a/mysql-test/r/rpl_timezone.result +++ b/mysql-test/r/rpl_timezone.result @@ -64,7 +64,7 @@ SET TIMESTAMP=100000000; SET @@session.time_zone='Europe/Moscow'; insert into t1 values ('20040101000000'), ('20040611093902'); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; delete from t1; set time_zone='UTC'; diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index eeb6e227c6a..3e4f29d7a01 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2620,6 +2620,15 @@ select found_rows(); found_rows() 1 DROP TABLE t1; +create table t1(f1 int, f2 int); +create table t2(f3 int); +select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,1)); +f1 +select f1 from t1,t2 where f1=f2 and (f1,NULL) = ((1,1)); +f1 +select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,NULL)); +f1 +drop table t1,t2; CREATE TABLE t1 ( city char(30) ); INSERT INTO t1 VALUES ('London'); INSERT INTO t1 VALUES ('Paris'); @@ -3029,3 +3038,26 @@ id 102 drop table t1, t2; drop view v1, v2, v3; +create table a ( +id int(11) not null default '0' +) engine=myisam default charset=latin1; +insert into a values (123),(191),(192); +create table b ( +id char(16) character set utf8 not null default '' +) engine=myisam default charset=latin1; +insert into b values ('58013'),('58014'),('58015'),('58016'); +create table c ( +a_id int(11) not null default '0', +b_id char(16) character set utf8 default null +) engine=myisam default charset=latin1; +insert into c values +(123,null),(123,null),(123,null),(123,null),(123,null),(123,'58013'); +select count(*) +from a inner join (c left join b on b.id = c.b_id) on a.id = c.a_id; +count(*) +6 +select count(*) +from a inner join (b right join c on b.id = c.b_id) on a.id = c.a_id; +count(*) +6 +drop table a, b, c; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index f9e6eae7e57..1b8cde6d3db 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3390,4 +3390,49 @@ s1 set sql_mode=@sm| drop table t3| drop procedure bug6127| +drop procedure if exists bug12589_1| +drop procedure if exists bug12589_2| +drop procedure if exists bug12589_3| +create procedure bug12589_1() +begin +declare spv1 decimal(3,3); +set spv1= 123.456; +set spv1 = 'test'; +create temporary table tm1 as select spv1; +show create table tm1; +drop temporary table tm1; +end| +create procedure bug12589_2() +begin +declare spv1 decimal(6,3); +set spv1= 123.456; +create temporary table tm1 as select spv1; +show create table tm1; +drop temporary table tm1; +end| +create procedure bug12589_3() +begin +declare spv1 decimal(6,3); +set spv1= -123.456; +create temporary table tm1 as select spv1; +show create table tm1; +drop temporary table tm1; +end| +call bug12589_1()| +Table Create Table +tm1 CREATE TEMPORARY TABLE `tm1` ( + `spv1` decimal(1,0) unsigned default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +Warnings: +Warning 1292 Truncated incorrect DECIMAL value: 'test' +call bug12589_2()| +Table Create Table +tm1 CREATE TEMPORARY TABLE `tm1` ( + `spv1` decimal(6,3) unsigned default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +call bug12589_3()| +Table Create Table +tm1 CREATE TEMPORARY TABLE `tm1` ( + `spv1` decimal(6,3) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1,t2; diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result index 6ceb1cda888..83099623e23 100644 --- a/mysql-test/r/sql_mode.result +++ b/mysql-test/r/sql_mode.result @@ -65,7 +65,7 @@ sql_mode NO_FIELD_OPTIONS,MYSQL323,MYSQL40,HIGH_NOT_PRECEDENCE show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` int(11) NOT NULL auto_increment, + `a` int(11) NOT NULL, `pseudo` varchar(35) NOT NULL default '', `email` varchar(60) NOT NULL default '', PRIMARY KEY (`a`), @@ -79,8 +79,8 @@ show create table t1; Table Create Table t1 CREATE TABLE "t1" ( "a" int(11) NOT NULL, - "pseudo" varchar(35) NOT NULL default '', - "email" varchar(60) NOT NULL default '', + "pseudo" varchar(35) character set latin2 NOT NULL default '', + "email" varchar(60) character set latin2 NOT NULL default '', PRIMARY KEY ("a"), UNIQUE KEY "email" ("email") ) @@ -140,6 +140,26 @@ t1 CREATE TABLE `t1` ( drop table t1 ; set @@SQL_MODE=NULL; ERROR 42000: Variable 'sql_mode' can't be set to the value of 'NULL' +set session sql_mode=ansi; +create table t1 +(f1 integer auto_increment primary key, +f2 timestamp default current_timestamp on update current_timestamp); +show create table t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "f1" int(11) NOT NULL auto_increment, + "f2" timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, + PRIMARY KEY ("f1") +) +set session sql_mode=no_field_options; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + `f2` timestamp NOT NULL default CURRENT_TIMESTAMP, + PRIMARY KEY (`f1`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE=''; show local variables like 'SQL_MODE'; Variable_name Value diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result index d2872878cb9..f68c4805d72 100644 --- a/mysql-test/r/system_mysql_db.result +++ b/mysql-test/r/system_mysql_db.result @@ -73,7 +73,7 @@ Table Create Table user CREATE TABLE `user` ( `Host` char(60) collate utf8_bin NOT NULL default '', `User` char(16) collate utf8_bin NOT NULL default '', - `Password` char(41) collate utf8_bin NOT NULL default '', + `Password` binary(41) NOT NULL default '', `Select_priv` enum('N','Y') character set utf8 NOT NULL default 'N', `Insert_priv` enum('N','Y') character set utf8 NOT NULL default 'N', `Update_priv` enum('N','Y') character set utf8 NOT NULL default 'N', diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index 56a2bceeccf..d7f5f9fa328 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -476,7 +476,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp CREATE TABLE t1 (a_dec DECIMAL(-1,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,1))' at line 1 CREATE TABLE t1 (a_dec DECIMAL(0,11)); -ERROR 42000: Scale may not be larger than the precision (column 'a_dec'). +ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 'a_dec'). create table t1(a decimal(7,3)); insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); select * from t1; diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index fc7e4c5f346..6b124caac14 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -226,6 +226,6 @@ reckey recdesc 109 Has 109 as key drop table t1; create table t1 (s1 float(0,2)); -ERROR 42000: For float(M,D) or double(M,D), M must be >= D (column 's1'). +ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 's1'). create table t1 (s1 float(1,2)); -ERROR 42000: For float(M,D) or double(M,D), M must be >= D (column 's1'). +ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 's1'). diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index d821339a229..be5e29ab662 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -68,10 +68,10 @@ NULL 1.1 NULL NULL NULL 1 show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `nullif(1.1, 1.1)` decimal(2,1) default NULL, - `nullif(1.1, 1.2)` decimal(2,1) default NULL, - `nullif(1.1, 0.11e1)` decimal(2,1) default NULL, - `nullif(1.0, 1)` decimal(2,1) default NULL, + `nullif(1.1, 1.1)` decimal(2,1) unsigned default NULL, + `nullif(1.1, 1.2)` decimal(2,1) unsigned default NULL, + `nullif(1.1, 0.11e1)` decimal(2,1) unsigned default NULL, + `nullif(1.0, 1)` decimal(2,1) unsigned default NULL, `nullif(1, 1.0)` int(1) default NULL, `nullif(1, 1.1)` int(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 @@ -174,9 +174,9 @@ create table t1 select round(15.4,-1), truncate(-5678.123451,-3), abs(-1.1), -(- show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `round(15.4,-1)` decimal(3,0) NOT NULL default '0', + `round(15.4,-1)` decimal(3,0) unsigned NOT NULL default '0', `truncate(-5678.123451,-3)` decimal(4,0) NOT NULL default '0', - `abs(-1.1)` decimal(3,1) NOT NULL default '0.0', + `abs(-1.1)` decimal(2,1) NOT NULL default '0.0', `-(-1.1)` decimal(2,1) NOT NULL default '0.0' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; @@ -781,7 +781,7 @@ create table t1 as select 0.5; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `0.5` decimal(2,1) NOT NULL default '0.0' + `0.5` decimal(2,1) unsigned NOT NULL default '0.0' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; select round(1.5),round(2.5); @@ -936,7 +936,7 @@ ERROR 42000: Too big scale 31 specified for column 'sl'. Maximum is 30. create table t1 (sl decimal(0,38)); ERROR 42000: Too big scale 38 specified for column 'sl'. Maximum is 30. create table t1 (sl decimal(0,30)); -ERROR 42000: Scale may not be larger than the precision (column 'sl'). +ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 'sl'). create table t1 (sl decimal(5, 5)); show create table t1; Table Create Table diff --git a/mysql-test/r/user_var-binlog.result b/mysql-test/r/user_var-binlog.result index e6f9ae1c82a..17ac8809d52 100644 --- a/mysql-test/r/user_var-binlog.result +++ b/mysql-test/r/user_var-binlog.result @@ -28,6 +28,6 @@ SET @`var2`:=_latin1 0x61 COLLATE `latin1_swedish_ci`; SET TIMESTAMP=10000; insert into t1 values (@var1),(@var2); # End of log file -ROLLBACK; +ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; drop table t1; diff --git a/mysql-test/std_data/ndb_config_mycnf1.cnf b/mysql-test/std_data/ndb_config_mycnf1.cnf new file mode 100644 index 00000000000..c680bfd8fa3 --- /dev/null +++ b/mysql-test/std_data/ndb_config_mycnf1.cnf @@ -0,0 +1,15 @@ +[cluster_config] +NoOfReplicas=1 +DataMemory=50M + +[cluster_config.jonas] +IndexMemory=50M +ndbd = localhost,localhost,localhost,localhost +ndb_mgmd = localhost +mysqld = localhost + +[cluster_config.ndbd.1] +DataMemory=25M + +[cluster_config.ndbd.2.jonas] +DataMemory=35M diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test index 2049c17580e..6220b4cbae7 100644 --- a/mysql-test/t/cast.test +++ b/mysql-test/t/cast.test @@ -27,6 +27,10 @@ select CONVERT(DATE "2004-01-22 21:45:33",CHAR); select CONVERT(DATE "2004-01-22 21:45:33",CHAR(4)); select CONVERT(DATE "2004-01-22 21:45:33",BINARY(4)); select CAST(DATE "2004-01-22 21:45:33" AS BINARY(4)); +select CAST(0xb3 as signed); +select CAST(0x8fffffffffffffff as signed); +select CAST(0xffffffffffffffff as unsigned); +select CAST(0xfffffffffffffffe as signed); select cast('-10a' as signed integer); select cast('a10' as unsigned integer); select 10+'a'; diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index f52e12849e4..33b06e9bc11 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -258,4 +258,17 @@ create table t2 (a int); select * from (select * from t1,t2) foo; drop table t1,t2; +# +# Bug#10586 - query works with 4.1.8, but not with 4.1.11 +# +create table t1 (ID int unsigned not null auto_increment, + DATA varchar(5) not null, primary key (ID)); +create table t2 (ID int unsigned not null auto_increment, + DATA varchar(5) not null, FID int unsigned not null, + primary key (ID)); +select A.* from (t1 inner join (select * from t2) as A on t1.ID = A.FID); +select t2.* from ((select * from t1) as A inner join t2 on A.ID = t2.FID); +select t2.* from (select * from t1) as A inner join t2 on A.ID = t2.FID; +drop table t1, t2; + # End of 4.1 tests diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 9023521c086..7d4e15163ef 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1268,6 +1268,7 @@ insert into t1 values ('8', '6'), ('4', '7'); select min(a) from t1; select min(b) from t1 where a='8'; drop table t1; + # End of 4.1 tests # @@ -1564,3 +1565,42 @@ SET FOREIGN_KEY_CHECKS=1; INSERT INTO t2 VALUES(3); DROP TABLE t2; +# +# Test that checksum table uses a consistent read Bug #12669 +# +connect (a,localhost,root,,); +connect (b,localhost,root,,); +connection a; +create table test_checksum(a int not null) engine=innodb DEFAULT CHARSET=latin1; +insert into test_checksum values (1),(2); +set autocommit=0; +checksum table test_checksum; +connection b; +insert into test_checksum values(3); +connection a; +# +# Here checksum should not see insert +# +checksum table test_checksum; +connection a; +commit; +checksum table test_checksum; +commit; +drop table test_checksum; +# +# autocommit = 1 +# +connection a; +create table test_checksum(a int not null) engine=innodb DEFAULT CHARSET=latin1; +insert into test_checksum values (1),(2); +set autocommit=1; +checksum table test_checksum; +connection b; +set autocommit=1; +insert into test_checksum values(3); +connection a; +# +# Here checksum sees insert +# +checksum table test_checksum; +drop table test_checksum; diff --git a/mysql-test/t/join_nested.test b/mysql-test/t/join_nested.test index 482c7f9f8b9..0592ec3152f 100644 --- a/mysql-test/t/join_nested.test +++ b/mysql-test/t/join_nested.test @@ -801,3 +801,34 @@ SELECT * FROM DROP VIEW v1,v2; DROP TABLE t1,t2,t3,t4; + +# +# Bug #13545: problem with NATURAL/USING joins. +# + +CREATE TABLE t1(a int); +CREATE TABLE t2(b int); +CREATE TABLE t3(c int, d int); +CREATE TABLE t4(d int); +CREATE TABLE t5(e int, f int); +CREATE TABLE t6(f int); +CREATE VIEW v1 AS + SELECT e FROM t5 JOIN t6 ON t5.e=t6.f; +CREATE VIEW v2 AS + SELECT e FROM t5 NATURAL JOIN t6; + +SELECT t1.a FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c JOIN t4 USING(d); +--error 1054 +SELECT t1.x FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c JOIN t4 USING(d); +SELECT t1.a FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c NATURAL JOIN t4; +--error 1054 +SELECT t1.x FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c NATURAL JOIN t4; +SELECT v1.e FROM v1 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d); +--error 1054 +SELECT v1.x FROM v1 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d); +SELECT v2.e FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d); +--error 1054 +SELECT v2.x FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d); + +DROP VIEW v1, v2; +DROP TABLE t1, t2, t3, t4, t5, t6; diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index 7cb8a089188..ff05867b7c1 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -296,29 +296,25 @@ drop table t1, t2; # non-debug build. But there is no guarantee that this will be always so. # create table t1 ( - a double(16,6), + a double(14,4), b varchar(10), index (a,b) ) engine=merge union=(t2,t3); create table t2 ( - a double(16,6), + a double(14,4), b varchar(10), index (a,b) ) engine=myisam; create table t3 ( - a double(16,6), + a double(14,4), b varchar(10), index (a,b) ) engine=myisam; insert into t2 values ( null, ''); -# We may have insufficient accuracy for 16 digits of '9'. -# Suppress a "truncate" warning due to accuracy problems. ---disable_warnings -insert into t2 values ( 9999999999.999999, ''); ---enable_warnings +insert into t2 values ( 9999999999.999, ''); insert into t3 select * from t2; select min(a), max(a) from t1; flush tables; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 2ce4b1071e2..7dafac2bde5 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -142,7 +142,7 @@ drop table t1; --exec $MYSQL_DUMP --skip-comments --databases test create database mysqldump_test_db character set latin2 collate latin2_bin; ---exec $MYSQL_DUMP --skip-comments --databases mysqldump_test_db; +--exec $MYSQL_DUMP --skip-comments --databases mysqldump_test_db drop database mysqldump_test_db; # @@ -758,17 +758,7 @@ select * from v3 where b in (1, 2, 3, 4, 5, 6, 7); create view v2 as select v3.a from v3, v1 where v1.a=v3.a and v3.b=3 limit 1; ---exec $MYSQL_DUMP test > var/tmp/bug10927.sql -drop view v1, v2, v3; -drop table t1; ---exec $MYSQL test < var/tmp/bug10927.sql - -# Without dropping the original tables in between ---exec $MYSQL_DUMP test > var/tmp/bug10927.sql ---exec $MYSQL test < var/tmp/bug10927.sql -show full tables; -show create view v1; -select * from v1; +--exec $MYSQL_DUMP --skip-comments test drop view v1, v2, v3; drop table t1; diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index c903749839d..11fbb023963 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -428,9 +428,8 @@ echo ; # ---------------------------------------------------------------------------- # Illegal use of exec -# Disabled, some shells prints the failed command regardless of pipes -#--error 1 -#--exec echo "--exec ';' 2> /dev/null" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "--exec false" | $MYSQL_TEST 2>&1 --error 1 --exec echo "--exec " | $MYSQL_TEST 2>&1 @@ -677,9 +676,8 @@ system echo "hej" > /dev/null; --exec echo "system;" | $MYSQL_TEST 2>&1 --error 1 --exec echo "system $NONEXISTSINFVAREABLI;" | $MYSQL_TEST 2>&1 -# Disabled, some shells prints the failed command regardless of pipes -#--error 1 -#--exec echo "system NonExistsinfComamdn 2> /dev/null;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "system false;" | $MYSQL_TEST 2>&1 --disable_abort_on_error system NonExistsinfComamdn; @@ -814,11 +812,11 @@ select "a" as col1, "c" as col2; # ---------------------------------------------------------------------------- # -x <file_name>, use the file specified after -x as the test file -#--exec $MYSQL_TEST < $MYSQL_TEST_DIR/include/mysqltest-x.inc 2>&1 -#--exec $MYSQL_TEST -x $MYSQL_TEST_DIR/include/mysqltest-x.inc 2>&1 -#--exec $MYSQL_TEST --result_file=$MYSQL_TEST_DIR/include/mysqltest-x.inc 2>&1 -#--error 1 -#--exec $MYSQL_TEST -x non_existing_file.inc 2>&1 +--exec $MYSQL_TEST < $MYSQL_TEST_DIR/include/mysqltest-x.inc +--exec $MYSQL_TEST -x $MYSQL_TEST_DIR/include/mysqltest-x.inc +--exec $MYSQL_TEST --test_file=$MYSQL_TEST_DIR/include/mysqltest-x.inc +--error 1 +--exec $MYSQL_TEST -x non_existing_file.inc 2>&1 # ---------------------------------------------------------------------------- diff --git a/mysql-test/t/ndb_config.test b/mysql-test/t/ndb_config.test index ab3063af672..9d1c107472f 100644 --- a/mysql-test/t/ndb_config.test +++ b/mysql-test/t/ndb_config.test @@ -6,5 +6,8 @@ --exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=nodeid,host,DataMemory,IndexMemory --type=ndbd 2> /dev/null --exec $NDB_TOOLS_DIR/ndb_config --no-defaults -r \\n -f " " --query=nodeid,host,DataMemory,IndexMemory --type=ndbd 2> /dev/null --exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=nodeid --type=ndbd --host=localhost 2> /dev/null +--exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=type,nodeid,host --config-file=$NDB_BACKUP_DIR/config.ini 2> /dev/null # End of 4.1 tests + +--exec $NDB_TOOLS_DIR/ndb_config --defaults-group-suffix=.jonas --defaults-file=$MYSQL_TEST_DIR/std_data/ndb_config_mycnf1.cnf --query=type,nodeid,host,IndexMemory,DataMemory --mycnf 2> /dev/null diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index d8b3f5ef953..11c5e8d7bc5 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -3,7 +3,7 @@ # --disable_warnings -drop table if exists t1, t2; +drop table if exists t1, t2, t3; --enable_warnings CREATE TABLE t1 ( @@ -600,3 +600,29 @@ explain select * from v1 where a between 3 and 4 and b between 1 and 2; drop view v1; drop table t1; + +# BUG#13455: +create table t3 (a int); +insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t1 (a varchar(10), filler char(200), key(a)) charset=binary; +insert into t1 values ('a',''); +insert into t1 values ('a ',''); +insert into t1 values ('a ', ''); +insert into t1 select concat('a', 1000 + A.a + 10 * (B.a + 10 * C.a)), '' + from t3 A, t3 B, t3 C; + +create table t2 (a varchar(10), filler char(200), key(a)); +insert into t2 select * from t1; + +--replace_column 9 # +explain select * from t1 where a between 'a' and 'a '; +--replace_column 9 # +explain select * from t1 where a = 'a' or a='a '; + +--replace_column 9 # +explain select * from t2 where a between 'a' and 'a '; +--replace_column 9 # +explain select * from t2 where a = 'a' or a='a '; + +drop table t1,t2,t3; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 4ad23be2649..f7de7239292 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -2181,6 +2181,16 @@ select found_rows(); DROP TABLE t1; +# +# Bug #13356 assertion failed in resolve_const_item() +# +create table t1(f1 int, f2 int); +create table t2(f3 int); +select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,1)); +select f1 from t1,t2 where f1=f2 and (f1,NULL) = ((1,1)); +select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,NULL)); +drop table t1,t2; + # End of 4.1 tests # @@ -2565,3 +2575,37 @@ select * from v1 left join v3 using (id); drop table t1, t2; drop view v1, v2, v3; + +# +# Bug #13597 Column in ON condition not resolved if references a table in +# nested right join. +# + +create table a ( + id int(11) not null default '0' +) engine=myisam default charset=latin1; + +insert into a values (123),(191),(192); + +create table b ( + id char(16) character set utf8 not null default '' +) engine=myisam default charset=latin1; + +insert into b values ('58013'),('58014'),('58015'),('58016'); + +create table c ( + a_id int(11) not null default '0', + b_id char(16) character set utf8 default null +) engine=myisam default charset=latin1; + +insert into c values +(123,null),(123,null),(123,null),(123,null),(123,null),(123,'58013'); + +-- both queries are equivalent +select count(*) +from a inner join (c left join b on b.id = c.b_id) on a.id = c.a_id; + +select count(*) +from a inner join (b right join c on b.id = c.b_id) on a.id = c.a_id; + +drop table a, b, c; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 65d4f89e2bb..e16e7456056 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -4265,6 +4265,57 @@ drop procedure bug6127| # +# BUG#12589: Assert when creating temp. table from decimal stored procedure +# variable +# +--disable_warnings +drop procedure if exists bug12589_1| +drop procedure if exists bug12589_2| +drop procedure if exists bug12589_3| +--enable_warnings +create procedure bug12589_1() +begin + declare spv1 decimal(3,3); + set spv1= 123.456; + + set spv1 = 'test'; + create temporary table tm1 as select spv1; + show create table tm1; + drop temporary table tm1; +end| + +create procedure bug12589_2() +begin + declare spv1 decimal(6,3); + set spv1= 123.456; + + create temporary table tm1 as select spv1; + show create table tm1; + drop temporary table tm1; +end| + +create procedure bug12589_3() +begin + declare spv1 decimal(6,3); + set spv1= -123.456; + + create temporary table tm1 as select spv1; + show create table tm1; + drop temporary table tm1; +end| + +# Note: The type of the field will match the value, not the declared +# type of the variable. (This is a type checking issue which +# might be changed later.) + +# Warning expected from "set spv1 = 'test'", the value is set to decimal "0". +call bug12589_1()| +# No warnings here +call bug12589_2()| +call bug12589_3()| + + +# # BUG#NNNN: New bug synopsis # #--disable_warnings diff --git a/mysql-test/t/sql_mode.test b/mysql-test/t/sql_mode.test index 10db520cd12..b11afe9e59d 100644 --- a/mysql-test/t/sql_mode.test +++ b/mysql-test/t/sql_mode.test @@ -86,6 +86,18 @@ drop table t1 ; --error 1231 set @@SQL_MODE=NULL; +# +# Bug #797: in sql_mode=ANSI, show create table ignores auto_increment +# +set session sql_mode=ansi; +create table t1 +(f1 integer auto_increment primary key, + f2 timestamp default current_timestamp on update current_timestamp); +show create table t1; +set session sql_mode=no_field_options; +show create table t1; +drop table t1; + # End of 4.1 tests # diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 2deec5ec63b..cf2a2676ab0 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -152,7 +152,7 @@ drop table t1; # bug #12694 (float(m,d) specifications) # ---error 1453 +--error 1427 create table t1 (s1 float(0,2)); ---error 1453 +--error 1427 create table t1 (s1 float(1,2)); diff --git a/mysys/default.c b/mysys/default.c index 5c631abebad..edd02402a2a 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -42,6 +42,7 @@ #include <winbase.h> #endif +const char *defaults_file=0; const char *defaults_group_suffix=0; char *defaults_extra_file=0; @@ -140,6 +141,9 @@ int my_search_option_files(const char *conf_file, int *argc, char ***argv, if (forced_extra_defaults) defaults_extra_file= (char *) forced_extra_defaults; + if (forced_default_file) + defaults_file= forced_default_file; + /* We can only handle 'defaults-group-suffix' if we are called from load_defaults() as otherwise we can't know the type of 'func_ctx' diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index b000af19aa0..63f5dc964da 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -165,7 +165,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, (ulong) info, (int) type, (ulong) seek_offset)); info->file= file; - info->type= 0; /* Don't set it until mutex are created */ + info->type= TYPE_NOT_SET; /* Don't set it until mutex are created */ info->pos_in_file= seek_offset; info->pre_close = info->pre_read = info->post_read = 0; info->arg = 0; @@ -1246,7 +1246,7 @@ int end_io_cache(IO_CACHE *info) if (info->type == SEQ_READ_APPEND) { /* Destroy allocated mutex */ - info->type=0; + info->type= TYPE_NOT_SET; #ifdef THREAD pthread_mutex_destroy(&info->append_buffer_lock); #endif diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index a86b6a2f1f4..69410e9faaa 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -161,10 +161,12 @@ KEY_CACHE *dflt_key_cache= &dflt_key_cache_var; #define FLUSH_CACHE 2000 /* sort this many blocks at once */ static int flush_all_key_blocks(KEY_CACHE *keycache); +#ifdef THREAD static void link_into_queue(KEYCACHE_WQUEUE *wqueue, struct st_my_thread_var *thread); static void unlink_from_queue(KEYCACHE_WQUEUE *wqueue, struct st_my_thread_var *thread); +#endif static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block); static void test_key_cache(KEY_CACHE *keycache, const char *where, my_bool lock); @@ -215,6 +217,7 @@ static void keycache_debug_print _VARARGS((const char *fmt,...)); #endif /* defined(KEYCACHE_DEBUG_LOG) && defined(KEYCACHE_DEBUG) */ #if defined(KEYCACHE_DEBUG) || !defined(DBUG_OFF) +#ifdef THREAD static long keycache_thread_id; #define KEYCACHE_THREAD_TRACE(l) \ KEYCACHE_DBUG_PRINT(l,("|thread %ld",keycache_thread_id)) @@ -226,6 +229,11 @@ static long keycache_thread_id; #define KEYCACHE_THREAD_TRACE_END(l) \ KEYCACHE_DBUG_PRINT(l,("]thread %ld",keycache_thread_id)) +#else /* THREAD */ +#define KEYCACHE_THREAD_TRACE(l) KEYCACHE_DBUG_PRINT(l,("")) +#define KEYCACHE_THREAD_TRACE_BEGIN(l) KEYCACHE_DBUG_PRINT(l,("")) +#define KEYCACHE_THREAD_TRACE_END(l) KEYCACHE_DBUG_PRINT(l,("")) +#endif /* THREAD */ #else #define KEYCACHE_THREAD_TRACE_BEGIN(l) #define KEYCACHE_THREAD_TRACE_END(l) @@ -492,6 +500,7 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, keycache_pthread_mutex_lock(&keycache->cache_lock); +#ifdef THREAD wqueue= &keycache->resize_queue; thread= my_thread_var; link_into_queue(wqueue, thread); @@ -500,6 +509,7 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, { keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock); } +#endif keycache->resize_in_flush= 1; if (flush_all_key_blocks(keycache)) @@ -512,12 +522,16 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, } keycache->resize_in_flush= 0; keycache->can_be_used= 0; +#ifdef THREAD while (keycache->cnt_for_resize_op) { KEYCACHE_DBUG_PRINT("resize_key_cache: wait", ("suspend thread %ld", thread->id)); keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock); } +#else + KEYCACHE_DBUG_ASSERT(keycache->cnt_for_resize_op == 0); +#endif end_key_cache(keycache, 0); /* Don't free mutex */ /* The following will work even if use_mem is 0 */ @@ -525,6 +539,7 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, division_limit, age_threshold); finish: +#ifdef THREAD unlink_from_queue(wqueue, thread); /* Signal for the next resize request to proceeed if any */ if (wqueue->last_thread) @@ -533,6 +548,7 @@ finish: ("thread %ld", wqueue->last_thread->next->id)); keycache_pthread_cond_signal(&wqueue->last_thread->next->suspend); } +#endif keycache_pthread_mutex_unlock(&keycache->cache_lock); return blocks; } @@ -553,6 +569,7 @@ static inline void inc_counter_for_resize_op(KEY_CACHE *keycache) */ static inline void dec_counter_for_resize_op(KEY_CACHE *keycache) { +#ifdef THREAD struct st_my_thread_var *last_thread; if (!--keycache->cnt_for_resize_op && (last_thread= keycache->resize_queue.last_thread)) @@ -561,6 +578,9 @@ static inline void dec_counter_for_resize_op(KEY_CACHE *keycache) ("thread %ld", last_thread->next->id)); keycache_pthread_cond_signal(&last_thread->next->suspend); } +#else + keycache->cnt_for_resize_op--; +#endif } /* @@ -650,6 +670,7 @@ void end_key_cache(KEY_CACHE *keycache, my_bool cleanup) } /* end_key_cache */ +#ifdef THREAD /* Link a thread into double-linked queue of waiting threads. @@ -786,6 +807,7 @@ static void release_queue(KEYCACHE_WQUEUE *wqueue) while (thread != last); wqueue->last_thread= NULL; } +#endif /* @@ -893,6 +915,7 @@ static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot, BLOCK_LINK **pins; KEYCACHE_DBUG_ASSERT(! (block->hash_link && block->hash_link->requests)); +#ifdef THREAD if (!hot && keycache->waiting_for_block.last_thread) { /* Signal that in the LRU warm sub-chain an available block has appeared */ @@ -929,6 +952,10 @@ static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot, #endif return; } +#else /* THREAD */ + KEYCACHE_DBUG_ASSERT(! (!hot && keycache->waiting_for_block.last_thread)); + /* Condition not transformed using DeMorgan, to keep the text identical */ +#endif /* THREAD */ pins= hot ? &keycache->used_ins : &keycache->used_last; ins= *pins; if (ins) @@ -1101,6 +1128,7 @@ static inline void remove_reader(BLOCK_LINK *block) static inline void wait_for_readers(KEY_CACHE *keycache, BLOCK_LINK *block) { +#ifdef THREAD struct st_my_thread_var *thread= my_thread_var; while (block->hash_link->requests) { @@ -1111,6 +1139,9 @@ static inline void wait_for_readers(KEY_CACHE *keycache, BLOCK_LINK *block) keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock); block->condvar= NULL; } +#else + KEYCACHE_DBUG_ASSERT(block->hash_link->requests == 0); +#endif } @@ -1140,6 +1171,7 @@ static void unlink_hash(KEY_CACHE *keycache, HASH_LINK *hash_link) if ((*hash_link->prev= hash_link->next)) hash_link->next->prev= hash_link->prev; hash_link->block= NULL; +#ifdef THREAD if (keycache->waiting_for_hash_link.last_thread) { /* Signal that a free hash link has appeared */ @@ -1175,6 +1207,9 @@ static void unlink_hash(KEY_CACHE *keycache, HASH_LINK *hash_link) hash_link); return; } +#else /* THREAD */ + KEYCACHE_DBUG_ASSERT(! (keycache->waiting_for_hash_link.last_thread)); +#endif /* THREAD */ hash_link->next= keycache->free_hash_list; keycache->free_hash_list= hash_link; } @@ -1240,6 +1275,7 @@ restart: } else { +#ifdef THREAD /* Wait for a free hash link */ struct st_my_thread_var *thread= my_thread_var; KEYCACHE_DBUG_PRINT("get_hash_link", ("waiting")); @@ -1252,6 +1288,9 @@ restart: keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock); thread->opt_info= NULL; +#else + KEYCACHE_DBUG_ASSERT(0); +#endif goto restart; } hash_link->file= file; @@ -1363,6 +1402,7 @@ restart: /* Wait intil the page is flushed on disk */ hash_link->requests--; { +#ifdef THREAD struct st_my_thread_var *thread= my_thread_var; add_to_queue(&block->wqueue[COND_FOR_SAVED], thread); do @@ -1373,6 +1413,16 @@ restart: &keycache->cache_lock); } while(thread->next); +#else + KEYCACHE_DBUG_ASSERT(0); + /* + Given the use of "resize_in_flush", it seems impossible + that this whole branch is ever entered in single-threaded case + because "(wrmode && keycache->resize_in_flush)" cannot be true. + TODO: Check this, and then put the whole branch into the + "#ifdef THREAD" guard. + */ +#endif } /* Invalidate page in the block if it has not been done yet */ if (block->status) @@ -1401,6 +1451,7 @@ restart: KEYCACHE_DBUG_PRINT("find_key_block", ("request waiting for old page to be saved")); { +#ifdef THREAD struct st_my_thread_var *thread= my_thread_var; /* Put the request into the queue of those waiting for the old page */ add_to_queue(&block->wqueue[COND_FOR_SAVED], thread); @@ -1413,6 +1464,10 @@ restart: &keycache->cache_lock); } while(thread->next); +#else + KEYCACHE_DBUG_ASSERT(0); + /* No parallel requests in single-threaded case */ +#endif } KEYCACHE_DBUG_PRINT("find_key_block", ("request for old page resubmitted")); @@ -1471,6 +1526,7 @@ restart: all of them must get the same block */ +#ifdef THREAD if (! keycache->used_last) { struct st_my_thread_var *thread= my_thread_var; @@ -1486,6 +1542,9 @@ restart: while (thread->next); thread->opt_info= NULL; } +#else + KEYCACHE_DBUG_ASSERT(keycache->used_last); +#endif block= hash_link->block; if (! block) { @@ -1674,6 +1733,7 @@ static void read_block(KEY_CACHE *keycache, KEYCACHE_DBUG_PRINT("read_block", ("secondary request waiting for new page to be read")); { +#ifdef THREAD struct st_my_thread_var *thread= my_thread_var; /* Put the request into a queue and wait until it can be processed */ add_to_queue(&block->wqueue[COND_FOR_REQUESTED], thread); @@ -1685,6 +1745,10 @@ static void read_block(KEY_CACHE *keycache, &keycache->cache_lock); } while (thread->next); +#else + KEYCACHE_DBUG_ASSERT(0); + /* No parallel requests in single-threaded case */ +#endif } KEYCACHE_DBUG_PRINT("read_block", ("secondary request: new page in cache")); @@ -1822,7 +1886,7 @@ byte *key_cache_read(KEY_CACHE *keycache, #ifndef THREAD /* This is only true if we where able to read everything in one block */ if (return_buffer) - return (block->buffer); + DBUG_RETURN(block->buffer); #endif buff+= read_length; filepos+= read_length+offset; @@ -2398,6 +2462,7 @@ restart: #endif block= first_in_switch; { +#ifdef THREAD struct st_my_thread_var *thread= my_thread_var; add_to_queue(&block->wqueue[COND_FOR_SAVED], thread); do @@ -2408,6 +2473,10 @@ restart: &keycache->cache_lock); } while (thread->next); +#else + KEYCACHE_DBUG_ASSERT(0); + /* No parallel requests in single-threaded case */ +#endif } #if defined(KEYCACHE_DEBUG) cnt++; @@ -2574,7 +2643,6 @@ static void test_key_cache(KEY_CACHE *keycache __attribute__((unused)), static void keycache_dump(KEY_CACHE *keycache) { FILE *keycache_dump_file=fopen(KEYCACHE_DUMP_FILE, "w"); - struct st_my_thread_var *thread_var= my_thread_var; struct st_my_thread_var *last; struct st_my_thread_var *thread; BLOCK_LINK *block; diff --git a/mysys/my_init.c b/mysys/my_init.c index abb1ad27f7b..f28f47e090e 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -127,11 +127,23 @@ my_bool my_init(void) void my_end(int infoflag) { - FILE *info_file; - if (!(info_file=DBUG_FILE)) - info_file=stderr; - DBUG_PRINT("info",("Shutting down")); - if (infoflag & MY_CHECK_ERROR || info_file != stderr) + /* + this code is suboptimal to workaround a bug in + Sun CC: Sun C++ 5.6 2004/06/02 for x86, and should not be + optimized until this compiler is not in use anymore + */ + FILE *info_file= DBUG_FILE; + my_bool print_info= (info_file != stderr); + DBUG_ENTER("my_end"); + if (!info_file) + { + info_file= stderr; + print_info= 0; + } + + DBUG_PRINT("info",("Shutting down: print_info: %d", print_info)); + if ((infoflag & MY_CHECK_ERROR) || print_info) + { /* Test if some file is left open */ if (my_file_opened | my_stream_opened) { @@ -141,7 +153,8 @@ void my_end(int infoflag) } } my_once_free(); - if (infoflag & MY_GIVE_INFO || info_file != stderr) + + if ((infoflag & MY_GIVE_INFO) || print_info) { #ifdef HAVE_GETRUSAGE struct rusage rus; diff --git a/ndb/include/kernel/GlobalSignalNumbers.h b/ndb/include/kernel/GlobalSignalNumbers.h index ff3690d60a5..98b6ce7d949 100644 --- a/ndb/include/kernel/GlobalSignalNumbers.h +++ b/ndb/include/kernel/GlobalSignalNumbers.h @@ -553,7 +553,6 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_STATISTICS_CONF 454 #define GSN_START_ORD 455 -/* 456 unused */ /* 457 unused */ #define GSN_EVENT_SUBSCRIBE_REQ 458 @@ -835,14 +834,6 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; /* Start Global Replication */ #define GSN_GREP_REQ 656 -/** - * Management server - */ -#define GSN_MGM_LOCK_CONFIG_REQ 657 -#define GSN_MGM_LOCK_CONFIG_REP 658 -#define GSN_MGM_UNLOCK_CONFIG_REQ 659 -#define GSN_MGM_UNLOCK_CONFIG_REP 660 - #define GSN_UTIL_CREATE_LOCK_REQ 132 #define GSN_UTIL_CREATE_LOCK_REF 133 #define GSN_UTIL_CREATE_LOCK_CONF 188 @@ -900,6 +891,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_RESUME_REQ 682 #define GSN_STOP_REQ 443 #define GSN_STOP_REF 444 +#define GSN_STOP_CONF 456 #define GSN_API_VERSION_REQ 697 #define GSN_API_VERSION_CONF 698 diff --git a/ndb/include/kernel/signaldata/ApiVersion.hpp b/ndb/include/kernel/signaldata/ApiVersion.hpp index 28281e7d186..a3774c9fba6 100644 --- a/ndb/include/kernel/signaldata/ApiVersion.hpp +++ b/ndb/include/kernel/signaldata/ApiVersion.hpp @@ -49,12 +49,11 @@ class ApiVersionConf { */ friend class MgmtSrv; public: - STATIC_CONST( SignalLength = 3 ); + STATIC_CONST( SignalLength = 4 ); Uint32 senderRef; Uint32 nodeId; //api node id Uint32 version; // Version of API node - - + Uint32 inet_addr; }; #endif diff --git a/ndb/include/kernel/signaldata/StopReq.hpp b/ndb/include/kernel/signaldata/StopReq.hpp index ea453ae115d..8e6a0b90a91 100644 --- a/ndb/include/kernel/signaldata/StopReq.hpp +++ b/ndb/include/kernel/signaldata/StopReq.hpp @@ -67,6 +67,13 @@ public: static bool getStopAbort(const Uint32 & requestInfo); }; +struct StopConf +{ + STATIC_CONST( SignalLength = 2 ); + Uint32 senderData; + Uint32 nodeState; +}; + class StopRef { /** @@ -86,7 +93,8 @@ public: OK = 0, NodeShutdownInProgress = 1, SystemShutdownInProgress = 2, - NodeShutdownWouldCauseSystemCrash = 3 + NodeShutdownWouldCauseSystemCrash = 3, + TransactionAbortFailed = 4 }; public: diff --git a/ndb/include/mgmapi/ndb_logevent.h b/ndb/include/mgmapi/ndb_logevent.h index d5744b0fffe..b69379545fc 100644 --- a/ndb/include/mgmapi/ndb_logevent.h +++ b/ndb/include/mgmapi/ndb_logevent.h @@ -148,9 +148,9 @@ extern "C" { /** NDB_MGM_EVENT_CATEGORY_INFO */ NDB_LE_InfoEvent = 49, - /* GREP */ - NDB_LE_GrepSubscriptionInfo = 52, - NDB_LE_GrepSubscriptionAlert = 53, + /* SINGLE USER */ + NDB_LE_SingleUser = 52, + /* NDB_LE_ UNUSED = 53, */ /** NDB_MGM_EVENT_CATEGORY_BACKUP */ NDB_LE_BackupStarted = 54, @@ -593,6 +593,11 @@ extern "C" { unsigned backup_id; unsigned error; } BackupAborted; + /** Log event data @ref NDB_LE_SingleUser */ + struct { + unsigned type; + unsigned node_id; + } SingleUser; #ifndef DOXYGEN_FIX }; #else diff --git a/ndb/src/common/debugger/EventLogger.cpp b/ndb/src/common/debugger/EventLogger.cpp index d18b0feb1ad..9a1dcb8a3e1 100644 --- a/ndb/src/common/debugger/EventLogger.cpp +++ b/ndb/src/common/debugger/EventLogger.cpp @@ -633,6 +633,27 @@ void getTextBackupAborted(QQQQ) { theData[3]); } +void getTextSingleUser(QQQQ) { + switch (theData[1]) + { + case 0: + BaseString::snprintf(m_text, m_text_len, "Entering single user mode"); + break; + case 1: + BaseString::snprintf(m_text, m_text_len, + "Entered single user mode " + "Node %d has exclusive access", theData[2]); + break; + case 2: + BaseString::snprintf(m_text, m_text_len,"Exiting single user mode"); + break; + default: + BaseString::snprintf(m_text, m_text_len, + "Unknown single user report %d", theData[1]); + break; + } +} + #if 0 BaseString::snprintf(m_text, m_text_len, @@ -716,6 +737,9 @@ const EventLoggerBase::EventRepLogLevelMatrix EventLoggerBase::matrix[] = { ROW(CreateLogBytes, LogLevel::llInfo, 11, Logger::LL_INFO ), ROW(InfoEvent, LogLevel::llInfo, 2, Logger::LL_INFO ), + //Single User + ROW(SingleUser, LogLevel::llInfo, 7, Logger::LL_INFO ), + // Backup ROW(BackupStarted, LogLevel::llBackup, 7, Logger::LL_INFO ), ROW(BackupCompleted, LogLevel::llBackup, 7, Logger::LL_INFO ), diff --git a/ndb/src/common/util/SimpleProperties.cpp b/ndb/src/common/util/SimpleProperties.cpp index c25aaea491a..c9251c6a854 100644 --- a/ndb/src/common/util/SimpleProperties.cpp +++ b/ndb/src/common/util/SimpleProperties.cpp @@ -51,11 +51,12 @@ SimpleProperties::Writer::add(const char * value, int len){ union { Uint32 lastWord; char lastBytes[4]; - }; - memcpy(lastBytes, + } tmp; + tmp.lastWord =0 ; + memcpy(tmp.lastBytes, value + putLen*4, len - putLen*4); - return putWord(lastWord); + return putWord(tmp.lastWord); } bool diff --git a/ndb/src/kernel/blocks/dbdict/Makefile.am b/ndb/src/kernel/blocks/dbdict/Makefile.am index 9a0d68f8148..3c1cf6735d9 100644 --- a/ndb/src/kernel/blocks/dbdict/Makefile.am +++ b/ndb/src/kernel/blocks/dbdict/Makefile.am @@ -1,12 +1,20 @@ -#SUBDIRS = printSchemafile - noinst_LIBRARIES = libdbdict.a +EXTRA_PROGRAMS = printSchemaFile libdbdict_a_SOURCES = Dbdict.cpp +printSchemaFile_SOURCES = printSchemaFile.cpp + include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/type_kernel.mk.am +LDADD += \ + $(top_builddir)/ndb/src/common/util/libgeneral.la \ + $(top_builddir)/ndb/src/common/portlib/libportlib.la \ + $(top_builddir)/dbug/libdbug.a \ + $(top_builddir)/mysys/libmysys.a \ + $(top_builddir)/strings/libmystrings.a + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp b/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp index 9858744a61d..f73654fd9d5 100644 --- a/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp +++ b/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp @@ -1,14 +1,3 @@ -#if 0 -make -f Makefile -f - printSchemaFile <<'_eof_' -printSchemaFile: printSchemaFile.cpp SchemaFile.hpp - $(CXXCOMPILE) -o $@ $@.cpp -L../../../common/util/.libs -lgeneral -ifneq ($(MYSQL_HOME),) - ln -sf `pwd`/$@ $(MYSQL_HOME)/bin/$@ -endif -_eof_ -exit $? -#endif - /* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify @@ -36,14 +25,19 @@ exit $? static const char* progname = 0; static bool allflag = false; static bool checkonly = false; -static int xitcode = 0; +static bool equalcontents = false; +static bool okquiet = false; static void usage() { - ndbout << "Usage " << progname - << " [-ac]" - << " P0.SchemaLog" << endl; + ndbout + << "Usage: " << progname << " [-aceq]" << " file ..." << endl + << "-a print also unused slots" << endl + << "-c check only (return status 1 on error)" << endl + << "-e check also that the files have identical contents" << endl + << "-q no output if file is ok" << endl + << "Example: " << progname << " -ceq ndb_*_fs/D[12]/DBDICT/P0.SchemaLog" << endl; } static void @@ -57,53 +51,78 @@ fill(const char * buf, int mod) } } -static void +static const char* +version(Uint32 v) +{ + static char buf[40]; + sprintf(buf, "%d.%d.%d", v >> 16, (v >> 8) & 0xFF, v & 0xFF); + return buf; +} + +static int print_head(const char * filename, const SchemaFile * sf) { + int retcode = 0; + if (! checkonly) { ndbout << "----- Schemafile: " << filename << " -----" << endl; - ndbout_c("Magic: %.*s ByteOrder: %.8x NdbVersion: %d.%d.%d FileSize: %d", + ndbout_c("Magic: %.*s ByteOrder: %.8x NdbVersion: %s FileSize: %d", sizeof(sf->Magic), sf->Magic, sf->ByteOrder, - sf->NdbVersion >> 16, - (sf->NdbVersion >> 8) & 0xFF, - sf->NdbVersion & 0xFF, + version(sf->NdbVersion), sf->FileSize); } + + if (memcmp(sf->Magic, "NDBSCHMA", sizeof(sf->Magic) != 0)) { + ndbout << filename << ": invalid header magic" << endl; + retcode = 1; + } + + if ((sf->NdbVersion >> 16) < 4 || (sf->NdbVersion >> 16) > 9) { + ndbout << filename << ": impossible version " << hex << sf->NdbVersion << endl; + retcode = 1; + } + + return retcode; } -static void -print_old(const char * filename, const SchemaFile * sf) +static int +print_old(const char * filename, const SchemaFile * sf, Uint32 sz) { - print_head(filename, sf); + int retcode = 0; + + if (print_head(filename, sf) != 0) + retcode = 1; for (Uint32 i = 0; i < sf->NoOfTableEntries; i++) { SchemaFile::TableEntry_old te = sf->TableEntries_old[i]; if (allflag || (te.m_tableState != SchemaFile::INIT && te.m_tableState != SchemaFile::DROP_TABLE_COMMITTED)) { - ndbout << "Table " << i << ":" - << " State = " << te.m_tableState - << " version = " << table_version_major(te.m_tableVersion) << - << "(" << table_version_minor(te.m_tableVersion) << ")" - << " type = " << te.m_tableType - << " noOfPages = " << te.m_noOfPages - << " gcp: " << te.m_gcp << endl; + if (! checkonly) + ndbout << "Table " << i << ":" + << " State = " << te.m_tableState + << " version = " << te.m_tableVersion + << " type = " << te.m_tableType + << " noOfPages = " << te.m_noOfPages + << " gcp: " << te.m_gcp << endl; } } + return retcode; } -static void +static int print(const char * filename, const SchemaFile * xsf, Uint32 sz) { int retcode = 0; - print_head(filename, xsf); + if (print_head(filename, xsf) != 0) + retcode = 1; assert(sizeof(SchemaFile) == NDB_SF_PAGE_SIZE); if (xsf->FileSize != sz || xsf->FileSize % NDB_SF_PAGE_SIZE != 0) { - ndbout << "***** invalid FileSize " << xsf->FileSize << endl; + ndbout << filename << ": invalid FileSize " << xsf->FileSize << endl; retcode = 1; } Uint32 noOfPages = xsf->FileSize / NDB_SF_PAGE_SIZE; @@ -112,19 +131,23 @@ print(const char * filename, const SchemaFile * xsf, Uint32 sz) ndbout << "----- Page: " << n << " (" << noOfPages << ") -----" << endl; } const SchemaFile * sf = &xsf[n]; + if (memcmp(sf->Magic, xsf->Magic, sizeof(sf->Magic)) != 0) { + ndbout << filename << ": page " << n << " invalid magic" << endl; + retcode = 1; + } if (sf->FileSize != xsf->FileSize) { - ndbout << "***** page " << n << " FileSize changed to " << sf->FileSize << "!=" << xsf->FileSize << endl; + ndbout << filename << ": page " << n << " FileSize changed to " << sf->FileSize << "!=" << xsf->FileSize << endl; retcode = 1; } Uint32 cs = 0; for (Uint32 j = 0; j < NDB_SF_PAGE_SIZE_IN_WORDS; j++) cs ^= ((const Uint32*)sf)[j]; if (cs != 0) { - ndbout << "***** page " << n << " invalid CheckSum" << endl; + ndbout << filename << ": page " << n << " invalid CheckSum" << endl; retcode = 1; } if (sf->NoOfTableEntries != NDB_SF_PAGE_ENTRIES) { - ndbout << "***** page " << n << " invalid NoOfTableEntries " << sf->NoOfTableEntries << endl; + ndbout << filename << ": page " << n << " invalid NoOfTableEntries " << sf->NoOfTableEntries << endl; retcode = 1; } for (Uint32 i = 0; i < NDB_SF_PAGE_ENTRIES; i++) { @@ -142,31 +165,41 @@ print(const char * filename, const SchemaFile * xsf, Uint32 sz) << " gcp: " << te.m_gcp << endl; } if (te.m_unused[0] != 0 || te.m_unused[1] != 0 || te.m_unused[2] != 0) { - ndbout << "***** entry " << j << " garbage in m_unused[3]" << endl; + ndbout << filename << ": entry " << j << " garbage in m_unused[3]" << endl; retcode = 1; } } } - if (retcode != 0) - xitcode = 1; - else if (checkonly) - ndbout << "ok: " << filename << endl; + return retcode; } NDB_COMMAND(printSchemafile, "printSchemafile", "printSchemafile", "Prints a schemafile", 16384) { progname = argv[0]; + int exitcode = 0; - while (argv[1][0] == '-') { + while (argc > 1 && argv[1][0] == '-') { if (strchr(argv[1], 'a') != 0) allflag = true; if (strchr(argv[1], 'c') != 0) checkonly = true; + if (strchr(argv[1], 'e') != 0) + equalcontents = true; + if (strchr(argv[1], 'q') != 0) + okquiet = true; + if (strchr(argv[1], 'h') != 0 || strchr(argv[1], '?') != 0) { + usage(); + return 0; + } argc--, argv++; } + const char * prevfilename = 0; + Uint32 * prevbuf = 0; + Uint32 prevbytes = 0; + while (argc > 1) { const char * filename = argv[1]; argc--, argv++; @@ -174,8 +207,9 @@ NDB_COMMAND(printSchemafile, struct stat sbuf; const int res = stat(filename, &sbuf); if (res != 0) { - ndbout << "Could not find file: \"" << filename << "\"" << endl; - return 1; + ndbout << filename << ": not found errno=" << errno << endl; + exitcode = 1; + continue; } const Uint32 bytes = sbuf.st_size; @@ -183,25 +217,56 @@ NDB_COMMAND(printSchemafile, FILE * f = fopen(filename, "rb"); if (f == 0) { - ndbout << "Failed to open file" << endl; + ndbout << filename << ": open failed errno=" << errno << endl; delete [] buf; - return 1; + exitcode = 1; + continue; } Uint32 sz = fread(buf, 1, bytes, f); fclose(f); if (sz != bytes) { - ndbout << "Failure while reading file" << endl; + ndbout << filename << ": read failed errno=" << errno << endl; + delete [] buf; + exitcode = 1; + continue; + } + + if (sz < 32) { + ndbout << filename << ": too short (no header)" << endl; delete [] buf; - return 1; + exitcode = 1; + continue; } SchemaFile* sf = (SchemaFile *)&buf[0]; + int ret; if (sf->NdbVersion < NDB_SF_VERSION_5_0_6) - print_old(filename, sf); + ret = print_old(filename, sf, sz); else - print(filename, sf, sz); - delete [] buf; + ret = print(filename, sf, sz); + + if (ret != 0) { + ndbout << filename << ": check failed" + << " version=" << version(sf->NdbVersion) << endl; + exitcode = 1; + } else if (! okquiet) { + ndbout << filename << ": ok" + << " version=" << version(sf->NdbVersion) << endl; + } + + if (equalcontents && prevfilename != 0) { + if (prevbytes != bytes || memcmp(prevbuf, buf, bytes) != 0) { + ndbout << filename << ": differs from " << prevfilename << endl; + exitcode = 1; + } + } + + prevfilename = filename; + delete [] prevbuf; + prevbuf = buf; + prevbytes = bytes; } - return xitcode; + delete [] prevbuf; + return exitcode; } diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp index 97b16f1dbc4..e50e6bd242b 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp @@ -1962,6 +1962,11 @@ Ndbcntr::execRESUME_REQ(Signal* signal){ //ResumeRef * const ref = (ResumeRef *)&signal->theData[0]; jamEntry(); + + signal->theData[0] = NDB_LE_SingleUser; + signal->theData[1] = 2; + sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); + //Uint32 senderData = req->senderData; //BlockReference senderRef = req->senderRef; NodeState newState(NodeState::SL_STARTED); @@ -2000,12 +2005,11 @@ Ndbcntr::execSTOP_REQ(Signal* signal){ return; } - if(c_stopRec.stopReq.senderRef != 0 && !singleuser){ - jam(); + if(c_stopRec.stopReq.senderRef != 0){ /** * Requested a system shutdown */ - if(StopReq::getSystemStop(req->requestInfo)){ + if(!singleuser && StopReq::getSystemStop(req->requestInfo)){ jam(); sendSignalWithDelay(reference(), GSN_STOP_REQ, signal, 100, StopReq::SignalLength); @@ -2027,23 +2031,28 @@ Ndbcntr::execSTOP_REQ(Signal* signal){ c_stopRec.stopReq = * req; c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond(); - if(StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) && !singleuser) { - jam(); - if(StopReq::getPerformRestart(c_stopRec.stopReq.requestInfo)){ - ((Configuration&)theConfiguration).stopOnError(false); - } - } if(!singleuser) { + if(StopReq::getSystemStop(c_stopRec.stopReq.requestInfo)) { + jam(); + if(StopReq::getPerformRestart(c_stopRec.stopReq.requestInfo)){ + ((Configuration&)theConfiguration).stopOnError(false); + } + } if(!c_stopRec.checkNodeFail(signal)){ jam(); return; } + signal->theData[0] = NDB_LE_NDBStopStarted; + signal->theData[1] = StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) ? 1 : 0; + sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); } - - signal->theData[0] = NDB_LE_NDBStopStarted; - signal->theData[1] = StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) ? 1 : 0; - sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); - + else + { + signal->theData[0] = NDB_LE_SingleUser; + signal->theData[1] = 0; + sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); + } + NodeState newState(NodeState::SL_STOPPING_1, StopReq::getSystemStop(c_stopRec.stopReq.requestInfo)); @@ -2125,9 +2134,11 @@ Ndbcntr::StopRecord::checkNodeFail(Signal* signal){ stopReq.senderRef = 0; - NodeState newState(NodeState::SL_STARTED); - - cntr.updateNodeState(signal, newState); + if (cntr.getNodeState().startLevel != NodeState::SL_SINGLEUSER) + { + NodeState newState(NodeState::SL_STARTED); + cntr.updateNodeState(signal, newState); + } signal->theData[0] = NDB_LE_NDBStopAborted; cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB); @@ -2223,12 +2234,24 @@ void Ndbcntr::execABORT_ALL_CONF(Signal* signal){ jamEntry(); if(c_stopRec.stopReq.singleuser) { jam(); + NodeState newState(NodeState::SL_SINGLEUSER); newState.setSingleUser(true); newState.setSingleUserApi(c_stopRec.stopReq.singleUserApi); updateNodeState(signal, newState); c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond(); + StopConf * const stopConf = (StopConf *)&signal->theData[0]; + stopConf->senderData = c_stopRec.stopReq.senderData; + stopConf->nodeState = (Uint32) NodeState::SL_SINGLEUSER; + sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_CONF, signal, StopConf::SignalLength, JBB); + + c_stopRec.stopReq.senderRef = 0; // the command is done + + signal->theData[0] = NDB_LE_SingleUser; + signal->theData[1] = 1; + signal->theData[2] = c_stopRec.stopReq.singleUserApi; + sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB); } else { @@ -2246,7 +2269,13 @@ void Ndbcntr::execABORT_ALL_CONF(Signal* signal){ void Ndbcntr::execABORT_ALL_REF(Signal* signal){ jamEntry(); - ndbrequire(false); + AbortAllRef *abortAllRef = (AbortAllRef *)&signal->theData[0]; + AbortAllRef::ErrorCode errorCode = (AbortAllRef::ErrorCode) abortAllRef->errorCode; + + StopRef * const stopRef = (StopRef *)&signal->theData[0]; + stopRef->senderData = c_stopRec.stopReq.senderData; + stopRef->errorCode = StopRef::TransactionAbortFailed; + sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB); } void diff --git a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp index 7052e0da98a..0f736c54555 100644 --- a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp +++ b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp @@ -2013,6 +2013,8 @@ Qmgr::execAPI_VERSION_REQ(Signal * signal) { else conf->version = 0; conf->nodeId = nodeId; + struct in_addr in= globalTransporterRegistry.get_connect_address(nodeId); + conf->inet_addr= in.s_addr; sendSignal(senderRef, GSN_API_VERSION_CONF, diff --git a/ndb/src/mgmapi/ndb_logevent.cpp b/ndb/src/mgmapi/ndb_logevent.cpp index 27e7c1f36f5..918ec5d6705 100644 --- a/ndb/src/mgmapi/ndb_logevent.cpp +++ b/ndb/src/mgmapi/ndb_logevent.cpp @@ -289,6 +289,8 @@ struct Ndb_logevent_body_row ndb_logevent_body[]= { ROW( BackupAborted, "backup_id", 2, backup_id), ROW( BackupAborted, "error", 3, error), + ROW( SingleUser, "type", 1, type), + ROW( SingleUser, "node_id", 2, node_id), { NDB_LE_ILLEGAL_TYPE, 0, 0, 0, 0, 0} }; diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index b4bbb3531ad..b5d1f38ba53 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -1443,9 +1443,8 @@ CommandInterpreter::executeEnterSingleUser(char* parameters) ndbout_c("Entering single user mode for node %d failed", nodeId); printError(); } else { - ndbout_c("Entering single user mode"); - ndbout_c("Access will be granted for API node %d only.", nodeId); - ndbout_c("Use ALL STATUS to see when single user mode has been entered."); + ndbout_c("Single user mode entered"); + ndbout_c("Access is granted for API node %d only.", nodeId); } } @@ -1458,7 +1457,7 @@ CommandInterpreter::executeExitSingleUser(char* parameters) printError(); } else { ndbout_c("Exiting single user mode in progress."); - ndbout_c("Use ALL STATUS to see when single user mode has been exited."); + ndbout_c("Use ALL STATUS or SHOW to see when single user mode has been exited."); } } diff --git a/ndb/src/mgmsrv/Config.cpp b/ndb/src/mgmsrv/Config.cpp index 5ff9cbe04ad..6ff5fb789f0 100644 --- a/ndb/src/mgmsrv/Config.cpp +++ b/ndb/src/mgmsrv/Config.cpp @@ -179,90 +179,3 @@ void Config::printConfigFile(NdbOut &out) const { } #endif } - -Uint32 -Config::getGenerationNumber() const { -#if 0 - Uint32 ret; - const Properties *prop = NULL; - - get("SYSTEM", &prop); - - if(prop != NULL) - if(prop->get("ConfigGenerationNumber", &ret)) - return ret; - - return 0; -#else - return 0; -#endif -} - -int -Config::setGenerationNumber(Uint32 gen) { -#if 0 - Properties *prop = NULL; - - getCopy("SYSTEM", &prop); - - if(prop != NULL) { - MGM_REQUIRE(prop->put("ConfigGenerationNumber", gen, true)); - MGM_REQUIRE(put("SYSTEM", prop, true)); - return 0; - } - return -1; -#else - return -1; -#endif -} - -bool -Config::change(const BaseString §ion, - const BaseString ¶m, - const BaseString &value) { -#if 0 - const char *name; - Properties::Iterator it(this); - - for(name = it.first(); name != NULL; name = it.next()) { - Properties *prop = NULL; - if(strcasecmp(section.c_str(), name) == 0) { - getCopy(name, &prop); - if(prop == NULL) /* doesn't exist */ - return false; - if(value == "") { - prop->remove(param.c_str()); - put(section.c_str(), prop, true); - } else { - PropertiesType t; - if(!prop->getTypeOf(param.c_str(), &t)) /* doesn't exist */ - return false; - switch(t) { - case PropertiesType_Uint32: - long val; - char *ep; - errno = 0; - val = strtol(value.c_str(), &ep, 0); - if(value.length() == 0 || *ep != '\0') /* not a number */ - return false; - if(errno == ERANGE) - return false; - prop->put(param.c_str(), (unsigned int)val, true); - put(section.c_str(), prop, true); - break; - case PropertiesType_char: - prop->put(param.c_str(), value.c_str(), true); - put(section.c_str(), prop, true); - break; - default: - return false; - } - } - break; - } - } - return true; -#else - return false; -#endif -} diff --git a/ndb/src/mgmsrv/Config.hpp b/ndb/src/mgmsrv/Config.hpp index b5e1e17b027..8e16ddf1810 100644 --- a/ndb/src/mgmsrv/Config.hpp +++ b/ndb/src/mgmsrv/Config.hpp @@ -60,16 +60,6 @@ public: printConfigFile(ndb); } - Uint32 getGenerationNumber() const; - int setGenerationNumber(Uint32); - - /** Change configuration - */ - bool change(const BaseString §ion, - const BaseString ¶m, - const BaseString &value); - - /** * Info */ diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp index 4e96047e54d..a870c395bd2 100644 --- a/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/ndb/src/mgmsrv/ConfigInfo.cpp @@ -241,6 +241,9 @@ struct DepricationTransform { static const DepricationTransform f_deprication[] = { { DB_TOKEN, "Discless", "Diskless", 0, 1 }, + { DB_TOKEN, "Id", "nodeid", 0, 1 }, + { API_TOKEN, "Id", "nodeid", 0, 1 }, + { MGM_TOKEN, "Id", "nodeid", 0, 1 }, { 0, 0, 0, 0, 0} }; @@ -405,9 +408,21 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 0, 0 }, { - CFG_NODE_ID, + KEY_INTERNAL, "Id", DB_TOKEN, + "", + ConfigInfo::CI_DEPRICATED, + false, + ConfigInfo::CI_INT, + MANDATORY, + "1", + STR_VALUE(MAX_NODES) }, + + { + CFG_NODE_ID, + "nodeid", + DB_TOKEN, "Number identifying the database node ("DB_TOKEN_PRINT")", ConfigInfo::CI_USED, false, @@ -1244,9 +1259,21 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 0, 0 }, { - CFG_NODE_ID, + KEY_INTERNAL, "Id", API_TOKEN, + "", + ConfigInfo::CI_DEPRICATED, + false, + ConfigInfo::CI_INT, + MANDATORY, + "1", + STR_VALUE(MAX_NODES) }, + + { + CFG_NODE_ID, + "nodeid", + API_TOKEN, "Number identifying application node ("API_TOKEN_PRINT")", ConfigInfo::CI_USED, false, @@ -1375,9 +1402,21 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 0, 0 }, { - CFG_NODE_ID, + KEY_INTERNAL, "Id", MGM_TOKEN, + "", + ConfigInfo::CI_DEPRICATED, + false, + ConfigInfo::CI_INT, + MANDATORY, + "1", + STR_VALUE(MAX_NODES) }, + + { + CFG_NODE_ID, + "nodeid", + MGM_TOKEN, "Number identifying the management server node ("MGM_TOKEN_PRINT")", ConfigInfo::CI_USED, false, @@ -2516,14 +2555,14 @@ bool transformNode(InitConfigFileParser::Context & ctx, const char * data){ Uint32 id; - if(!ctx.m_currentSection->get("Id", &id)){ + if(!ctx.m_currentSection->get("nodeid", &id) && !ctx.m_currentSection->get("Id", &id)){ Uint32 nextNodeId= 1; ctx.m_userProperties.get("NextNodeId", &nextNodeId); id= nextNodeId; while (ctx.m_userProperties.get("AllocatedNodeId_", id, &id)) id++; ctx.m_userProperties.put("NextNodeId", id+1, true); - ctx.m_currentSection->put("Id", id); + ctx.m_currentSection->put("nodeid", id); #if 0 ctx.reportError("Mandatory parameter Id missing from section " "[%s] starting at line: %d", @@ -2531,7 +2570,7 @@ transformNode(InitConfigFileParser::Context & ctx, const char * data){ return false; #endif } else if(ctx.m_userProperties.get("AllocatedNodeId_", id, &id)) { - ctx.reportError("Duplicate Id in section " + ctx.reportError("Duplicate nodeid in section " "[%s] starting at line: %d", ctx.fname, ctx.m_sectionLineno); return false; @@ -3356,6 +3395,7 @@ transform(InitConfigFileParser::Context & ctx, PropertiesType oldType; require(ctx.m_currentSection->getTypeOf(oldName, &oldType)); ConfigInfo::Type newType = ctx.m_info->getType(ctx.m_currentInfo, newName); + if(!((oldType == PropertiesType_Uint32 || oldType == PropertiesType_Uint64) && (newType == ConfigInfo::CI_INT || newType == ConfigInfo::CI_INT64 || newType == ConfigInfo::CI_BOOL))){ ndbout << "oldType: " << (int)oldType << ", newType: " << (int)newType << endl; diff --git a/ndb/src/mgmsrv/InitConfigFileParser.cpp b/ndb/src/mgmsrv/InitConfigFileParser.cpp index 822e10c89aa..233458ddf83 100644 --- a/ndb/src/mgmsrv/InitConfigFileParser.cpp +++ b/ndb/src/mgmsrv/InitConfigFileParser.cpp @@ -31,8 +31,10 @@ static void require(bool v) { if(!v) abort();} //**************************************************************************** // Ctor / Dtor //**************************************************************************** -InitConfigFileParser::InitConfigFileParser(){ +InitConfigFileParser::InitConfigFileParser(FILE * out) +{ m_info = new ConfigInfo(); + m_errstream = out ? out : stdout; } InitConfigFileParser::~InitConfigFileParser() { @@ -42,11 +44,12 @@ InitConfigFileParser::~InitConfigFileParser() { //**************************************************************************** // Read Config File //**************************************************************************** -InitConfigFileParser::Context::Context(const ConfigInfo * info) +InitConfigFileParser::Context::Context(const ConfigInfo * info, FILE * out) : m_userProperties(true), m_configValues(1000, 20) { m_config = new Properties(true); m_defaults = new Properties(true); + m_errstream = out; } InitConfigFileParser::Context::~Context(){ @@ -61,10 +64,10 @@ Config * InitConfigFileParser::parseConfig(const char * filename) { FILE * file = fopen(filename, "r"); if(file == 0){ - ndbout << "Error opening file: " << filename << endl; + fprintf(m_errstream, "Error opening file: %s\n", filename); return 0; } - + Config * ret = parseConfig(file); fclose(file); return ret; @@ -75,7 +78,7 @@ InitConfigFileParser::parseConfig(FILE * file) { char line[MAX_LINE_LENGTH]; - Context ctx(m_info); + Context ctx(m_info, m_errstream); ctx.m_lineno = 0; ctx.m_currentSection = 0; @@ -160,6 +163,13 @@ InitConfigFileParser::parseConfig(FILE * file) { ctx.reportError("Could not store section of configuration file."); return 0; } + + return run_config_rules(ctx); +} + +Config* +InitConfigFileParser::run_config_rules(Context& ctx) +{ for(size_t i = 0; ConfigInfo::m_ConfigRules[i].m_configRule != 0; i++){ ctx.type = InitConfigFileParser::Undefined; ctx.m_currentSection = 0; @@ -267,10 +277,10 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) } if (status == ConfigInfo::CI_DEPRICATED) { const char * desc = m_info->getDescription(ctx.m_currentInfo, fname); - if(desc){ + if(desc && desc[0]){ ctx.reportWarning("[%s] %s is depricated, use %s instead", ctx.fname, fname, desc); - } else { + } else if (desc == 0){ ctx.reportWarning("[%s] %s is depricated", ctx.fname, fname); } } @@ -571,8 +581,9 @@ InitConfigFileParser::Context::reportError(const char * fmt, ...){ va_start(ap, fmt); if (fmt != 0) BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap); - ndbout << "Error line " << m_lineno << ": " << buf << endl; va_end(ap); + fprintf(m_errstream, "Error line %d: %s\n", + m_lineno, buf); //m_currentSection->print(); } @@ -585,6 +596,358 @@ InitConfigFileParser::Context::reportWarning(const char * fmt, ...){ va_start(ap, fmt); if (fmt != 0) BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap); - ndbout << "Warning line " << m_lineno << ": " << buf << endl; va_end(ap); + fprintf(m_errstream, "Warning line %d: %s\n", + m_lineno, buf); +} + +#include <my_sys.h> +#include <my_getopt.h> + +static int order = 1; +static +my_bool +parse_mycnf_opt(int, const struct my_option * opt, char * value) +{ + if(opt->comment) + ((struct my_option *)opt)->app_type++; + else + ((struct my_option *)opt)->app_type = order++; + return 0; +} + +bool +InitConfigFileParser::store_in_properties(Vector<struct my_option>& options, + InitConfigFileParser::Context& ctx, + const char * name) +{ + for(unsigned i = 0; i<options.size(); i++) + { + if(options[i].comment && + options[i].app_type && + strcmp(options[i].comment, name) == 0) + { + Uint64 value_int; + switch(options[i].var_type){ + case GET_INT: + value_int = *(Uint32*)options[i].value; + break; + case GET_LL: + value_int = *(Uint64*)options[i].value; + break; + case GET_STR: + ctx.m_currentSection->put(options[i].name, (char*)options[i].value); + continue; + default: + abort(); + } + + const char * fname = options[i].name; + if (!m_info->verify(ctx.m_currentInfo, fname, value_int)) { + ctx.reportError("Illegal value %lld for parameter %s.\n" + "Legal values are between %Lu and %Lu", + value_int, fname, + m_info->getMin(ctx.m_currentInfo, fname), + m_info->getMax(ctx.m_currentInfo, fname)); + return false; + } + if (options[i].var_type == GET_INT) + ctx.m_currentSection->put(options[i].name, (Uint32)value_int); + else + ctx.m_currentSection->put(options[i].name, value_int); + } + } + return true; } + +bool +InitConfigFileParser::handle_mycnf_defaults(Vector<struct my_option>& options, + InitConfigFileParser::Context& ctx, + const char * name) +{ + strcpy(ctx.fname, name); + ctx.type = InitConfigFileParser::DefaultSection; + ctx.m_currentSection = new Properties(true); + ctx.m_userDefaults = NULL; + require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0); + require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname)) != 0); + if(store_in_properties(options, ctx, name)) + return storeSection(ctx); + return false; +} + +static +int +load_defaults(Vector<struct my_option>& options, const char* groups[]) +{ + int argc = 1; + const char * argv[] = { "ndb_mgmd", 0, 0, 0, 0 }; + BaseString file; + BaseString extra_file; + BaseString group_suffix; + + const char *save_file = defaults_file; + char *save_extra_file = defaults_extra_file; + const char *save_group_suffix = defaults_group_suffix; + + if (defaults_file) + { + file.assfmt("--defaults-file=%s", defaults_file); + argv[argc++] = file.c_str(); + } + + if (defaults_extra_file) + { + extra_file.assfmt("--defaults-extra-file=%s", defaults_extra_file); + argv[argc++] = extra_file.c_str(); + } + + if (defaults_group_suffix) + { + group_suffix.assfmt("--defaults-group-suffix=%s", defaults_group_suffix); + argv[argc++] = group_suffix.c_str(); + } + + char ** tmp = (char**)argv; + int ret = load_defaults("my", groups, &argc, &tmp); + + defaults_file = save_file; + defaults_extra_file = save_extra_file; + defaults_group_suffix = save_group_suffix; + + if (ret == 0) + { + return handle_options(&argc, &tmp, options.getBase(), parse_mycnf_opt); + } + + return ret; +} + +bool +InitConfigFileParser::load_mycnf_groups(Vector<struct my_option> & options, + InitConfigFileParser::Context& ctx, + const char * name, + const char *groups[]) +{ + unsigned i; + Vector<struct my_option> copy; + for(i = 0; i<options.size(); i++) + { + if(options[i].comment && strcmp(options[i].comment, name) == 0) + { + options[i].app_type = 0; + copy.push_back(options[i]); + } + } + + struct my_option end; + bzero(&end, sizeof(end)); + copy.push_back(end); + + if (load_defaults(copy, groups)) + return false; + + return store_in_properties(copy, ctx, name); +} + +Config * +InitConfigFileParser::parse_mycnf() +{ + int i; + Config * res = 0; + Vector<struct my_option> options; + for(i = 0; i<ConfigInfo::m_NoOfParams; i++) + { + if (strcmp(ConfigInfo::m_ParamInfo[i]._section, "DB") == 0 || + strcmp(ConfigInfo::m_ParamInfo[i]._section, "API") == 0 || + strcmp(ConfigInfo::m_ParamInfo[i]._section, "MGM") == 0) + { + struct my_option opt; + bzero(&opt, sizeof(opt)); + const ConfigInfo::ParamInfo& param = ConfigInfo::m_ParamInfo[i]; + switch(param._type){ + case ConfigInfo::CI_BOOL: + opt.value = (gptr*)malloc(sizeof(int)); + opt.var_type = GET_INT; + break; + case ConfigInfo::CI_INT: + opt.value = (gptr*)malloc(sizeof(int)); + opt.var_type = GET_INT; + require(convertStringToUint64(param._min, (Uint64&)opt.min_value)); + require(convertStringToUint64(param._max, (Uint64&)opt.max_value)); + break; + case ConfigInfo::CI_INT64: + opt.value = (gptr*)malloc(sizeof(Int64)); + opt.var_type = GET_LL; + require(convertStringToUint64(param._min, (Uint64&)opt.min_value)); + require(convertStringToUint64(param._max, (Uint64&)opt.max_value)); + break; + case ConfigInfo::CI_STRING: + opt.value = (gptr*)malloc(sizeof(char *)); + opt.var_type = GET_STR; + break; + default: + continue; + } + opt.name = param._fname; + opt.id = 256; + opt.app_type = 0; + opt.arg_type = REQUIRED_ARG; + opt.comment = param._section; + options.push_back(opt); + } + } + + struct my_option *ndbd, *ndb_mgmd, *mysqld, *api; + + /** + * Add ndbd, ndb_mgmd, api/mysqld + */ + { + struct my_option opt; + bzero(&opt, sizeof(opt)); + opt.name = "ndbd"; + opt.id = 256; + opt.value = (gptr*)malloc(sizeof(char*)); + opt.var_type = GET_STR; + opt.arg_type = REQUIRED_ARG; + options.push_back(opt); + ndbd = &options.back(); + + opt.name = "ndb_mgmd"; + opt.id = 256; + opt.value = (gptr*)malloc(sizeof(char*)); + opt.var_type = GET_STR; + opt.arg_type = REQUIRED_ARG; + options.push_back(opt); + ndb_mgmd = &options.back(); + + opt.name = "mysqld"; + opt.id = 256; + opt.value = (gptr*)malloc(sizeof(char*)); + opt.var_type = GET_STR; + opt.arg_type = REQUIRED_ARG; + options.push_back(opt); + mysqld = &options.back(); + + opt.name = "api"; + opt.id = 256; + opt.value = (gptr*)malloc(sizeof(char*)); + opt.var_type = GET_STR; + opt.arg_type = REQUIRED_ARG; + options.push_back(opt); + api = &options.back(); + + bzero(&opt, sizeof(opt)); + options.push_back(opt); + } + + + Context ctx(m_info, m_errstream); + const char *groups[]= { "cluster_config", 0 }; + if (load_defaults(options, groups)) + goto end; + + ctx.m_lineno = 0; + if(!handle_mycnf_defaults(options, ctx, "DB")) + goto end; + if(!handle_mycnf_defaults(options, ctx, "API")) + goto end; + if(!handle_mycnf_defaults(options, ctx, "MGM")) + goto end; + + { + struct sect { struct my_option* src; const char * name; } sections[] = + { + { ndb_mgmd, "MGM" } + ,{ ndbd, "DB" } + ,{ mysqld, "API" } + ,{ api, "API" } + ,{ 0, 0 }, { 0, 0 } + }; + + for(i = 0; sections[i].src; i++) + { + for(int j = i + 1; sections[j].src; j++) + { + if (sections[j].src->app_type < sections[i].src->app_type) + { + sect swap = sections[i]; + sections[i] = sections[j]; + sections[j] = swap; + } + } + } + + ctx.type = InitConfigFileParser::Section; + ctx.m_sectionLineno = ctx.m_lineno; + for(i = 0; sections[i].src; i++) + { + if (sections[i].src->app_type) + { + strcpy(ctx.fname, sections[i].name); + BaseString str(*(char**)sections[i].src->value); + Vector<BaseString> list; + str.split(list, ","); + + const char * defaults_groups[] = { 0, 0, 0 }; + for(unsigned j = 0; j<list.size(); j++) + { + BaseString group_idx; + BaseString group_host; + group_idx.assfmt("%s.%s.%d", groups[0], + sections[i].src->name, j + 1); + group_host.assfmt("%s.%s.%s", groups[0], + sections[i].src->name, list[j].c_str()); + defaults_groups[0] = group_idx.c_str(); + if(list[j].length()) + defaults_groups[1] = group_host.c_str(); + else + defaults_groups[1] = 0; + + ctx.m_currentSection = new Properties(true); + ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults); + require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0); + require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname))!= 0); + ctx.m_currentSection->put("HostName", list[j].c_str()); + if(!load_mycnf_groups(options, ctx, sections[i].name, + defaults_groups)) + goto end; + + if(!storeSection(ctx)) + goto end; + } + } + } + } + + res = run_config_rules(ctx); + +end: + for(i = 0; options[i].name; i++) + free(options[i].value); + + return res; +} + +template class Vector<struct my_option>; + +#if 0 +struct my_option +{ + const char *name; /* Name of the option */ + int id; /* unique id or short option */ + const char *comment; /* option comment, for autom. --help */ + gptr *value; /* The variable value */ + gptr *u_max_value; /* The user def. max variable value */ + const char **str_values; /* Pointer to possible values */ + ulong var_type; + enum get_opt_arg_type arg_type; + longlong def_value; /* Default value */ + longlong min_value; /* Min allowed value */ + longlong max_value; /* Max allowed value */ + longlong sub_size; /* Subtract this from given value */ + long block_size; /* Value should be a mult. of this */ + int app_type; /* To be used by an application */ +}; +#endif diff --git a/ndb/src/mgmsrv/InitConfigFileParser.hpp b/ndb/src/mgmsrv/InitConfigFileParser.hpp index 1ea0a094ccd..616fd5a62fb 100644 --- a/ndb/src/mgmsrv/InitConfigFileParser.hpp +++ b/ndb/src/mgmsrv/InitConfigFileParser.hpp @@ -34,11 +34,12 @@ class ConfigInfo; * object if the config file has correct syntax and semantic. */ class InitConfigFileParser { + FILE * m_errstream; public: /** * Constructor */ - InitConfigFileParser(); + InitConfigFileParser(FILE * errstream = stdout); ~InitConfigFileParser(); /** @@ -50,6 +51,7 @@ public: */ Config * parseConfig(FILE * file); Config * parseConfig(const char * filename); + Config * parse_mycnf(); /** * Parser context struct @@ -60,7 +62,7 @@ public: * Context = Which section in init config file we are currently parsing */ struct Context { - Context(const ConfigInfo *); + Context(const ConfigInfo *, FILE * out); ~Context(); ContextSectionType type; ///< Section type (e.g. default section,section) @@ -82,6 +84,7 @@ public: ConfigValuesFactory m_configValues; // public: + FILE * m_errstream; void reportError(const char * msg, ...); void reportWarning(const char * msg, ...); }; @@ -122,6 +125,21 @@ private: * Information about parameters (min, max values etc) */ ConfigInfo* m_info; + + bool handle_mycnf_defaults(Vector<struct my_option>& options, + InitConfigFileParser::Context& ctx, + const char * name); + + bool load_mycnf_groups(Vector<struct my_option> & options, + InitConfigFileParser::Context& ctx, + const char * name, + const char *groups[]); + + bool store_in_properties(Vector<struct my_option>& options, + InitConfigFileParser::Context& ctx, + const char * name); + + Config* run_config_rules(Context& ctx); }; #endif // InitConfigFileParser_H diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index d946b4af4a7..5a07c5fa1ec 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -67,6 +67,16 @@ #define DEBUG(x) #endif +#define INIT_SIGNAL_SENDER(ss,nodeId) \ + SignalSender ss(theFacade); \ + ss.lock(); /* lock will be released on exit */ \ + {\ + int result = okToSendTo(nodeId, true);\ + if (result != 0) {\ + return result;\ + }\ + } + extern int global_flag_send_heartbeat_now; extern int g_no_nodeid_checks; extern my_bool opt_core; @@ -90,55 +100,6 @@ MgmtSrvr::logLevelThread_C(void* m) return 0; } -void * -MgmtSrvr::signalRecvThread_C(void *m) -{ - MgmtSrvr *mgm = (MgmtSrvr*)m; - mgm->signalRecvThreadRun(); - return 0; -} - -class SigMatch -{ -public: - int gsn; - void (MgmtSrvr::* function)(NdbApiSignal *signal); - - SigMatch() { gsn = 0; function = NULL; }; - - SigMatch(int _gsn, - void (MgmtSrvr::* _function)(NdbApiSignal *signal)) { - gsn = _gsn; - function = _function; - }; - - bool check(NdbApiSignal *signal) { - if(signal->readSignalNumber() == gsn) - return true; - return false; - }; - -}; - -void -MgmtSrvr::signalRecvThreadRun() -{ - Vector<SigMatch> siglist; - siglist.push_back(SigMatch(GSN_MGM_LOCK_CONFIG_REQ, - &MgmtSrvr::handle_MGM_LOCK_CONFIG_REQ)); - siglist.push_back(SigMatch(GSN_MGM_UNLOCK_CONFIG_REQ, - &MgmtSrvr::handle_MGM_UNLOCK_CONFIG_REQ)); - - while(!_isStopThread) { - SigMatch *handler = NULL; - NdbApiSignal *signal = NULL; - if(m_signalRecvQueue.waitFor(siglist, &handler, &signal, DEFAULT_TIMEOUT)) { - if(handler->function != 0) - (this->*handler->function)(signal); - } - } -} - extern EventLogger g_eventLogger; static NdbOut& @@ -426,15 +387,12 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server, _isStopThread = false; _logLevelThread = NULL; _logLevelThreadSleep = 500; - m_signalRecvThread = NULL; theFacade = 0; m_newConfig = NULL; if (config_filename) m_configFilename.assign(config_filename); - else - m_configFilename.assign("config.ini"); m_nextConfigGenerationNumber = 0; @@ -469,7 +427,7 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server, _config= readConfig(); if (_config == 0) { ndbout << "Unable to read config file" << endl; - require(false); + exit(-1); } } @@ -654,12 +612,6 @@ MgmtSrvr::start(BaseString &error_string) "MgmtSrvr_Loglevel", NDB_THREAD_PRIO_LOW); - m_signalRecvThread = NdbThread_Create(signalRecvThread_C, - (void **)this, - 32768, - "MgmtSrvr_Service", - NDB_THREAD_PRIO_LOW); - DBUG_RETURN(true); } @@ -668,10 +620,6 @@ MgmtSrvr::start(BaseString &error_string) //**************************************************************************** MgmtSrvr::~MgmtSrvr() { - while (theSignalIdleList != NULL) { - freeSignal(); - } - if(theFacade != 0){ theFacade->stop_instance(); delete theFacade; @@ -699,10 +647,6 @@ MgmtSrvr::~MgmtSrvr() NdbThread_Destroy(&_logLevelThread); } - if (m_signalRecvThread != NULL) { - NdbThread_WaitFor(m_signalRecvThread, &res); - NdbThread_Destroy(&m_signalRecvThread); - } if (m_config_retriever) delete m_config_retriever; } @@ -710,21 +654,21 @@ MgmtSrvr::~MgmtSrvr() //**************************************************************************** //**************************************************************************** -int MgmtSrvr::okToSendTo(NodeId processId, bool unCond) +int MgmtSrvr::okToSendTo(NodeId nodeId, bool unCond) { - if(processId == 0) + if(nodeId == 0) return 0; - if (getNodeType(processId) != NDB_MGM_NODE_TYPE_NDB) + if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB) return WRONG_PROCESS_TYPE; // Check if we have contact with it if(unCond){ - if(theFacade->theClusterMgr->getNodeInfo(processId).connected) + if(theFacade->theClusterMgr->getNodeInfo(nodeId).connected) return 0; return NO_CONTACT_WITH_PROCESS; } - if (theFacade->get_node_alive(processId) == 0) { + if (theFacade->get_node_alive(nodeId) == 0) { return NO_CONTACT_WITH_PROCESS; } else { return 0; @@ -745,241 +689,454 @@ void report_unknown_signal(SimpleSignal *signal) ****************************************************************************/ int -MgmtSrvr::start(int processId) +MgmtSrvr::start(int nodeId) { - int result; - - result = okToSendTo(processId, true); - if (result != 0) { - return result; - } - - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } - - StartOrd* const startOrd = CAST_PTR(StartOrd, signal->getDataPtrSend()); - signal->set(TestOrd::TraceAPI, CMVMI, GSN_START_ORD, StartOrd::SignalLength); + INIT_SIGNAL_SENDER(ss,nodeId); + SimpleSignal ssig; + StartOrd* const startOrd = CAST_PTR(StartOrd, ssig.getDataPtrSend()); + ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_START_ORD, StartOrd::SignalLength); startOrd->restartInfo = 0; - result = sendSignal(processId, NO_WAIT, signal, true); - if (result == -1) { - return SEND_OR_RECEIVE_FAILED; + return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; +} + +/***************************************************************************** + * Version handling + *****************************************************************************/ + +int +MgmtSrvr::versionNode(int nodeId, Uint32 &version, const char **address) +{ + version= 0; + if (getOwnNodeId() == nodeId) + { + /** + * If we're inquiring about our own node id, + * We know what version we are (version implies connected for mgm) + * but would like to find out from elsewhere what address they're using + * to connect to us. This means that secondary mgm servers + * can list ip addresses for mgm servers. + * + * If we don't get an address (i.e. no db nodes), + * we get the address from the configuration. + */ + sendVersionReq(nodeId, version, address); + version= NDB_VERSION; + if(!*address) + { + ndb_mgm_configuration_iterator + iter(*_config->m_configValues, CFG_SECTION_NODE); + unsigned tmp= 0; + for(iter.first();iter.valid();iter.next()) + { + if(iter.get(CFG_NODE_ID, &tmp)) require(false); + if((unsigned)nodeId!=tmp) + continue; + if(iter.get(CFG_NODE_HOST, address)) require(false); + break; + } + } } - + else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) + { + ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(nodeId); + if(node.connected) + version= node.m_info.m_version; + *address= get_connect_address(nodeId); + } + else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API || + getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) + { + return sendVersionReq(nodeId, version, address); + } + + return 0; +} + +int +MgmtSrvr::sendVersionReq(int v_nodeId, Uint32 &version, const char **address) +{ + SignalSender ss(theFacade); + ss.lock(); + + SimpleSignal ssig; + ApiVersionReq* req = CAST_PTR(ApiVersionReq, ssig.getDataPtrSend()); + req->senderRef = ss.getOwnRef(); + req->nodeId = v_nodeId; + ssig.set(ss, TestOrd::TraceAPI, QMGR, GSN_API_VERSION_REQ, + ApiVersionReq::SignalLength); + + int do_send = 1; + NodeId nodeId; + + while (1) + { + if (do_send) + { + bool next; + nodeId = 0; + + while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && + okToSendTo(nodeId, true) != 0); + + const ClusterMgr::Node &node= + theFacade->theClusterMgr->getNodeInfo(nodeId); + if(next && node.m_state.startLevel != NodeState::SL_STARTED) + { + NodeId tmp=nodeId; + while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && + okToSendTo(nodeId, true) != 0); + if(!next) + nodeId= tmp; + } + + if(!next) return NO_CONTACT_WITH_DB_NODES; + + if (ss.sendSignal(nodeId, &ssig) != SEND_OK) { + return SEND_OR_RECEIVE_FAILED; + } + do_send = 0; + } + + SimpleSignal *signal = ss.waitFor(); + + int gsn = signal->readSignalNumber(); + switch (gsn) { + case GSN_API_VERSION_CONF: { + const ApiVersionConf * const conf = + CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr()); + assert(conf->nodeId == v_nodeId); + version = conf->version; + struct in_addr in; + in.s_addr= conf->inet_addr; + *address= inet_ntoa(in); + return 0; + } + case GSN_NF_COMPLETEREP:{ + const NFCompleteRep * const rep = + CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr()); + if (rep->failedNodeId == nodeId) + do_send = 1; // retry with other node + continue; + } + case GSN_NODE_FAILREP:{ + const NodeFailRep * const rep = + CAST_CONSTPTR(NodeFailRep, signal->getDataPtr()); + if (NodeBitmask::get(rep->theNodes,nodeId)) + do_send = 1; // retry with other node + continue; + } + default: + report_unknown_signal(signal); + return SEND_OR_RECEIVE_FAILED; + } + break; + } // while(1) + return 0; } -/** - * Restart one database node +/* + * Common method for handeling all STOP_REQ signalling that + * is used by Stopping, Restarting and Single user commands */ -int -MgmtSrvr::restartNode(int processId, bool nostart, - bool initalStart, bool abort, - StopCallback callback, void * anyData) + +int MgmtSrvr::sendSTOP_REQ(NodeId nodeId, + NodeBitmask &stoppedNodes, + Uint32 singleUserNodeId, + bool abort, + bool stop, + bool restart, + bool nostart, + bool initialStart) { - int result; + stoppedNodes.clear(); - if(m_stopRec.singleUserMode) - return 5060; + SignalSender ss(theFacade); + ss.lock(); // lock will be released on exit - if(m_stopRec.inUse){ - return 5029; - } - - result = okToSendTo(processId, true); - if (result != 0) { - return result; - } - - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } + SimpleSignal ssig; + StopReq* const stopReq = CAST_PTR(StopReq, ssig.getDataPtrSend()); + ssig.set(ss, TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength); - StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend()); - signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength); - stopReq->requestInfo = 0; - StopReq::setSystemStop(stopReq->requestInfo, false); - StopReq::setPerformRestart(stopReq->requestInfo, true); - StopReq::setNoStart(stopReq->requestInfo, nostart); - StopReq::setInitialStart(stopReq->requestInfo, initalStart); - StopReq::setStopAbort(stopReq->requestInfo, abort); - stopReq->singleuser = 0; stopReq->apiTimeout = 5000; stopReq->transactionTimeout = 1000; stopReq->readOperationTimeout = 1000; stopReq->operationTimeout = 1000; stopReq->senderData = 12; - stopReq->senderRef = _ownReference; - - m_stopRec.singleUserMode = false; - m_stopRec.sentCount = 1; - m_stopRec.reply = 0; - m_stopRec.nodeId = processId; - m_stopRec.anyData = anyData; - m_stopRec.callback = callback; - m_stopRec.inUse = true; - - if(callback == NULL){ - Uint32 timeOut = 0; - timeOut += stopReq->apiTimeout; - timeOut += stopReq->transactionTimeout; - timeOut += stopReq->readOperationTimeout; - timeOut += stopReq->operationTimeout; - timeOut *= 3; - result = sendRecSignal(processId, WAIT_STOP, signal, true, timeOut); - } else { - result = sendSignal(processId, NO_WAIT, signal, true); + stopReq->senderRef = ss.getOwnRef(); + if (singleUserNodeId) + { + stopReq->singleuser = 1; + stopReq->singleUserApi = singleUserNodeId; + StopReq::setSystemStop(stopReq->requestInfo, false); + StopReq::setPerformRestart(stopReq->requestInfo, false); + StopReq::setStopAbort(stopReq->requestInfo, false); } - - if (result == -1 && theWaitState != WAIT_NODEFAILURE) { - m_stopRec.inUse = false; - return SEND_OR_RECEIVE_FAILED; + else + { + stopReq->singleuser = 0; + StopReq::setSystemStop(stopReq->requestInfo, stop); + StopReq::setPerformRestart(stopReq->requestInfo, restart); + StopReq::setStopAbort(stopReq->requestInfo, abort); + StopReq::setNoStart(stopReq->requestInfo, nostart); + StopReq::setInitialStart(stopReq->requestInfo, initialStart); } - if(callback == 0){ - m_stopRec.inUse = false; - return m_stopRec.reply; - } else { - return 0; + // send the signals + NodeBitmask nodes; + if (nodeId) + { + { + int r; + if((r = okToSendTo(nodeId, true)) != 0) + return r; + } + { + if (ss.sendSignal(nodeId, &ssig) != SEND_OK) + return SEND_OR_RECEIVE_FAILED; + } + nodes.set(nodeId); } + else + while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) + { + if(okToSendTo(nodeId, true) == 0) + { + SendStatus result = ss.sendSignal(nodeId, &ssig); + if (result == SEND_OK) + nodes.set(nodeId); + } + } + + // now wait for the replies + int error = 0; + while (!nodes.isclear()) + { + SimpleSignal *signal = ss.waitFor(); + int gsn = signal->readSignalNumber(); + switch (gsn) { + case GSN_STOP_REF:{ + const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr()); + const NodeId nodeId = refToNode(signal->header.theSendersBlockRef); +#ifdef VM_TRACE + ndbout_c("Node %d refused stop", nodeId); +#endif + assert(nodes.get(nodeId)); + nodes.clear(nodeId); + error = translateStopRef(ref->errorCode); + break; + } + case GSN_STOP_CONF:{ + const StopConf * const ref = CAST_CONSTPTR(StopConf, signal->getDataPtr()); + const NodeId nodeId = refToNode(signal->header.theSendersBlockRef); +#ifdef VM_TRACE + ndbout_c("Node %d single user mode", nodeId); +#endif + assert(nodes.get(nodeId)); + assert(singleUserNodeId != 0); + nodes.clear(nodeId); + stoppedNodes.set(nodeId); + break; + } + case GSN_NF_COMPLETEREP:{ + const NFCompleteRep * const rep = + CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr()); +#ifdef VM_TRACE + ndbout_c("Node %d fail completed", rep->failedNodeId); +#endif + break; + } + case GSN_NODE_FAILREP:{ + const NodeFailRep * const rep = + CAST_CONSTPTR(NodeFailRep, signal->getDataPtr()); + NodeBitmask failedNodes; + failedNodes.assign(NodeBitmask::Size, rep->theNodes); +#ifdef VM_TRACE + { + ndbout << "Failed nodes:"; + for (unsigned i = 0; i < 32*NodeBitmask::Size; i++) + if(failedNodes.get(i)) + ndbout << " " << i; + ndbout << endl; + } +#endif + failedNodes.bitAND(nodes); + if (!failedNodes.isclear()) + { + nodes.bitANDC(failedNodes); // clear the failed nodes + if (singleUserNodeId == 0) + stoppedNodes.bitOR(failedNodes); + } + break; + } + default: + report_unknown_signal(signal); +#ifdef VM_TRACE + ndbout_c("Unknown signal %d", gsn); +#endif + return SEND_OR_RECEIVE_FAILED; + } + } + return error; } -/** - * Restart all database nodes +/* + * Stop one node */ -int -MgmtSrvr::restart(bool nostart, bool initalStart, bool abort, - int * stopCount, StopCallback callback, void * anyData) + +int MgmtSrvr::stopNode(int nodeId, bool abort) { - if(m_stopRec.singleUserMode) - return 5060; + NodeBitmask nodes; + return sendSTOP_REQ(nodeId, + nodes, + 0, + abort, + false, + false, + false, + false); +} + +/* + * Perform system shutdown + */ - if(m_stopRec.inUse){ - return 5029; - } - - m_stopRec.singleUserMode = false; - m_stopRec.sentCount = 0; - m_stopRec.reply = 0; - m_stopRec.nodeId = 0; - m_stopRec.anyData = anyData; - m_stopRec.callback = callback; - m_stopRec.inUse = true; - - /** - * Restart all database nodes into idle ("no-started") state - */ - Uint32 timeOut = 0; - NodeId nodeId = 0; +int MgmtSrvr::stop(int * stopCount, bool abort) +{ NodeBitmask nodes; - while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){ - if(okToSendTo(nodeId, true) == 0){ + int ret = sendSTOP_REQ(0, + nodes, + 0, + abort, + true, + false, + false, + false); + if (stopCount) + *stopCount = nodes.count(); + return ret; +} + +/* + * Enter single user mode on all live nodes + */ - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } - - StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend()); - signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, - StopReq::SignalLength); - - stopReq->requestInfo = 0; - stopReq->singleuser = 0; - StopReq::setSystemStop(stopReq->requestInfo, true); - StopReq::setPerformRestart(stopReq->requestInfo, true); - if (callback == 0) { - // Start node in idle ("no-started") state - StopReq::setNoStart(stopReq->requestInfo, 1); - } else { - StopReq::setNoStart(stopReq->requestInfo, nostart); - } - StopReq::setInitialStart(stopReq->requestInfo, initalStart); - StopReq::setStopAbort(stopReq->requestInfo, abort); - - stopReq->apiTimeout = 5000; - stopReq->transactionTimeout = 1000; - stopReq->readOperationTimeout = 1000; - stopReq->operationTimeout = 1000; - stopReq->senderData = 12; - stopReq->senderRef = _ownReference; - - timeOut += stopReq->apiTimeout; - timeOut += stopReq->transactionTimeout; - timeOut += stopReq->readOperationTimeout; - timeOut += stopReq->operationTimeout; - timeOut *= 3; - - m_stopRec.sentCount++; - int res; - if(callback == 0){ - res = sendSignal(nodeId, WAIT_STOP, signal, true); - } else { - res = sendSignal(nodeId, NO_WAIT, signal, true); - } - - if(res != -1){ - nodes.set(nodeId); - } - } - } - - if(stopCount != 0){ - * stopCount = m_stopRec.sentCount; +int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId) +{ + if (getNodeType(singleUserNodeId) != NDB_MGM_NODE_TYPE_API) + return 5062; + NodeId nodeId = 0; + ClusterMgr::Node node; + while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) + { + node = theFacade->theClusterMgr->getNodeInfo(nodeId); + if((node.m_state.startLevel != NodeState::SL_STARTED) && + (node.m_state.startLevel != NodeState::SL_NOTHING)) + return 5063; } + NodeBitmask nodes; + int ret = sendSTOP_REQ(0, + nodes, + singleUserNodeId, + false, + false, + false, + false, + false); + if (stopCount) + *stopCount = nodes.count(); + return ret; +} + +/* + * Perform node restart + */ - if(m_stopRec.sentCount == 0){ - m_stopRec.inUse = false; - return 0; - } - - if(callback != 0){ - return 0; - } - - theFacade->lock_mutex(); - int waitTime = timeOut/m_stopRec.sentCount; - if (receiveOptimisedResponse(waitTime) != 0) { - m_stopRec.inUse = false; - return -1; - } - +int MgmtSrvr::restartNode(int nodeId, bool nostart, bool initialStart, + bool abort) +{ + NodeBitmask nodes; + return sendSTOP_REQ(nodeId, + nodes, + 0, + abort, + false, + true, + nostart, + initialStart); +} + +/* + * Perform system restart + */ + +int MgmtSrvr::restart(bool nostart, bool initialStart, + bool abort, int * stopCount ) +{ + NodeBitmask nodes; + int ret = sendSTOP_REQ(0, + nodes, + 0, + abort, + true, + true, + true, + initialStart); + + if (ret) + return ret; + + if (stopCount) + *stopCount = nodes.count(); + +#ifdef VM_TRACE + ndbout_c("Stopped %d nodes", nodes.count()); +#endif /** * Here all nodes were correctly stopped, * so we wait for all nodes to be contactable */ - nodeId = 0; + int waitTime = 12000; + NodeId nodeId = 0; NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime; - while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB) && nodes.get(nodeId)) { + + ndbout_c(" %d", nodes.get(1)); + ndbout_c(" %d", nodes.get(2)); + + while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) { + if (!nodes.get(nodeId)) + continue; enum ndb_mgm_node_status s; s = NDB_MGM_NODE_STATUS_NO_CONTACT; +#ifdef VM_TRACE + ndbout_c("Waiting for %d not started", nodeId); +#endif while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0) { Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0; Uint32 connectCount = 0; bool system; + const char *address; status(nodeId, &s, &version, &startPhase, - &system, &dynamicId, &nodeGroup, &connectCount); + &system, &dynamicId, &nodeGroup, &connectCount, &address); NdbSleep_MilliSleep(100); waitTime = (maxTime - NdbTick_CurrentMillisecond()); } } - if(nostart){ - m_stopRec.inUse = false; + if(nostart) return 0; - } /** * Now we start all database nodes (i.e. we make them non-idle) * We ignore the result we get from the start command. */ nodeId = 0; - while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB) && nodes.get(nodeId)) { + while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) { + if (!nodes.get(nodeId)) + continue; int result; result = start(nodeId); DEBUG("Starting node " << nodeId << " with result " << result); @@ -988,455 +1145,43 @@ MgmtSrvr::restart(bool nostart, bool initalStart, bool abort, * Maybe the user only wanted to restart a subset of the nodes. * It is also easy for the user to check which nodes have * started and which nodes have not. - * - * if (result != 0) { - * m_stopRec.inUse = false; - * return result; - * } */ } - m_stopRec.inUse = false; - return 0; -} - -/***************************************************************************** - * Version handling - *****************************************************************************/ - -int -MgmtSrvr::versionNode(int processId, bool abort, - VersionCallback callback, void * anyData) -{ - int version; - - if(m_versionRec.inUse) - return OPERATION_IN_PROGRESS; - - m_versionRec.callback = callback; - m_versionRec.inUse = true ; - - if (getOwnNodeId() == processId) - { - version= NDB_VERSION; - } - else if (getNodeType(processId) == NDB_MGM_NODE_TYPE_NDB) - { - ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(processId); - if(node.connected) - version= node.m_info.m_version; - else - version= 0; - } - else if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API || - getNodeType(processId) == NDB_MGM_NODE_TYPE_MGM) - { - return sendVersionReq(processId); - } - else - version= 0; - - if(m_versionRec.callback != 0) - m_versionRec.callback(processId, version, this,0); - m_versionRec.inUse = false ; - - m_versionRec.version[processId]= version; - - return 0; -} - -int -MgmtSrvr::sendVersionReq(int processId) -{ - Uint32 ndbnode=0; - int result; - for(Uint32 i = 0; i<MAX_NODES; i++) { - if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) { - if(okToSendTo(i, true) == 0) - { - ndbnode = i; - break; - } - } - } - - if (ndbnode == 0) { - m_versionRec.inUse = false; - if(m_versionRec.callback != 0) - m_versionRec.callback(processId, 0, this,0); - return NO_CONTACT_WITH_CLUSTER; - } - - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - m_versionRec.inUse = false; - if(m_versionRec.callback != 0) - m_versionRec.callback(processId, 0, this,0); - return COULD_NOT_ALLOCATE_MEMORY; - } - ApiVersionReq* req = CAST_PTR(ApiVersionReq, signal->getDataPtrSend()); - req->senderRef = _ownReference; - req->nodeId = processId; - - signal->set(TestOrd::TraceAPI, QMGR, GSN_API_VERSION_REQ, - ApiVersionReq::SignalLength); - - - // if(m_versionRec.callback == 0){ - Uint32 timeOut = 0; - timeOut = 10000; - result = sendRecSignal(ndbnode, WAIT_VERSION, signal, true, timeOut); - //} else { - //result = sendSignal(processId, NO_WAIT, signal, true); - // } - - if (result == -1) { - m_versionRec.inUse = false; - if(m_versionRec.callback != 0) - m_versionRec.callback(processId, 0, this,0); - m_versionRec.version[processId] = 0; - return SEND_OR_RECEIVE_FAILED; - } - - m_versionRec.inUse = false; - return 0; -} - -int -MgmtSrvr::version(int * stopCount, bool abort, - VersionCallback callback, void * anyData) -{ - ClusterMgr::Node node; - int version; - - if(m_versionRec.inUse) - return 1; - - m_versionRec.callback = callback; - m_versionRec.inUse = true ; - Uint32 i; - for(i = 0; i<MAX_NODES; i++) { - if (getNodeType(i) == NDB_MGM_NODE_TYPE_MGM) { - m_versionRec.callback(i, NDB_VERSION, this,0); - } - } - for(i = 0; i<MAX_NODES; i++) { - if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) { - node = theFacade->theClusterMgr->getNodeInfo(i); - version = node.m_info.m_version; - if(theFacade->theClusterMgr->getNodeInfo(i).connected) - m_versionRec.callback(i, version, this,0); - else - m_versionRec.callback(i, 0, this,0); - - } - } - for(i = 0; i<MAX_NODES; i++) { - if (getNodeType(i) == NDB_MGM_NODE_TYPE_API) { - return sendVersionReq(i); - } - } - return 0; } -int -MgmtSrvr::stopNode(int processId, bool abort, StopCallback callback, - void * anyData) - -{ - if(m_stopRec.singleUserMode) - return 5060; - - if(m_stopRec.inUse) - return 5029; - - int result; - - result = okToSendTo(processId, true); - if (result != 0) { - return result; - } - - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } - - StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend()); - signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength); - - stopReq->requestInfo = 0; - stopReq->singleuser = 0; - StopReq::setPerformRestart(stopReq->requestInfo, false); - StopReq::setSystemStop(stopReq->requestInfo, false); - StopReq::setStopAbort(stopReq->requestInfo, abort); - - stopReq->apiTimeout = 5000; - stopReq->transactionTimeout = 1000; - stopReq->readOperationTimeout = 1000; - stopReq->operationTimeout = 1000; - stopReq->senderData = 12; - stopReq->senderRef = _ownReference; - - m_stopRec.sentCount = 1; - m_stopRec.reply = 0; - m_stopRec.nodeId = processId; - m_stopRec.anyData = anyData; - m_stopRec.callback = callback; - m_stopRec.inUse = true; - - if(callback == NULL){ - Uint32 timeOut = 0; - timeOut += stopReq->apiTimeout; - timeOut += stopReq->transactionTimeout; - timeOut += stopReq->readOperationTimeout; - timeOut += stopReq->operationTimeout; - timeOut *= 3; - result = sendRecSignal(processId, WAIT_STOP, signal, true, timeOut); - } else { - result = sendSignal(processId, NO_WAIT, signal, true); - } - - if (result == -1) { - m_stopRec.inUse = false; - return SEND_OR_RECEIVE_FAILED; - } - - if(callback == 0){ - m_stopRec.inUse = false; - return m_stopRec.reply; - } else { - return 0; - } -} - -int -MgmtSrvr::stop(int * stopCount, bool abort, StopCallback callback, - void * anyData) -{ - if(m_stopRec.singleUserMode) - return 5060; - - if(m_stopRec.inUse){ - return 5029; - } - - m_stopRec.singleUserMode = false; - m_stopRec.sentCount = 0; - m_stopRec.reply = 0; - m_stopRec.nodeId = 0; - m_stopRec.anyData = anyData; - m_stopRec.callback = callback; - m_stopRec.inUse = true; - - NodeId nodeId = 0; - Uint32 timeOut = 0; - while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){ - if(okToSendTo(nodeId, true) == 0){ - - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } - - StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend()); - signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, - StopReq::SignalLength); - - stopReq->requestInfo = 0; - stopReq->singleuser = 0; - StopReq::setSystemStop(stopReq->requestInfo, true); - StopReq::setPerformRestart(stopReq->requestInfo, false); - StopReq::setStopAbort(stopReq->requestInfo, abort); - - stopReq->apiTimeout = 5000; - stopReq->transactionTimeout = 1000; - stopReq->readOperationTimeout = 1000; - stopReq->operationTimeout = 1000; - stopReq->senderData = 12; - stopReq->senderRef = _ownReference; - - timeOut += stopReq->apiTimeout; - timeOut += stopReq->transactionTimeout; - timeOut += stopReq->readOperationTimeout; - timeOut += stopReq->operationTimeout; - timeOut *= 3; - - m_stopRec.sentCount++; - if(callback == 0) - sendSignal(nodeId, WAIT_STOP, signal, true); - else - sendSignal(nodeId, NO_WAIT, signal, true); - } - } - - if(stopCount != 0) - * stopCount = m_stopRec.sentCount; - - if(m_stopRec.sentCount > 0){ - if(callback == 0){ - theFacade->lock_mutex(); - receiveOptimisedResponse(timeOut / m_stopRec.sentCount); - } else { - return 0; - } - } - - m_stopRec.inUse = false; - return m_stopRec.reply; -} - -/***************************************************************************** - * Single user mode - ****************************************************************************/ - int -MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId, - EnterSingleCallback callback, void * anyData) +MgmtSrvr::exitSingleUser(int * stopCount, bool abort) { - if(m_stopRec.singleUserMode) { - return 5060; - } - - if (getNodeType(singleUserNodeId) != NDB_MGM_NODE_TYPE_API) { - return 5062; - } - ClusterMgr::Node node; - - for(Uint32 i = 0; i<MAX_NODES; i++) { - if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) { - node = theFacade->theClusterMgr->getNodeInfo(i); - if((node.m_state.startLevel != NodeState::SL_STARTED) && - (node.m_state.startLevel != NodeState::SL_NOTHING)) { - return 5063; - } - } - } - - if(m_stopRec.inUse){ - return 5029; - } - - if(singleUserNodeId == 0) - return 1; - m_stopRec.singleUserMode = true; - m_stopRec.sentCount = 0; - m_stopRec.reply = 0; - m_stopRec.nodeId = 0; - m_stopRec.anyData = anyData; - m_stopRec.callback = callback; - m_stopRec.inUse = true; - NodeId nodeId = 0; - Uint32 timeOut = 0; - while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){ - if(okToSendTo(nodeId, true) == 0){ - - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } - - StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend()); - signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, - StopReq::SignalLength); - - stopReq->requestInfo = 0; - stopReq->singleuser = 1; - stopReq->singleUserApi = singleUserNodeId; - StopReq::setSystemStop(stopReq->requestInfo, false); - StopReq::setPerformRestart(stopReq->requestInfo, false); - StopReq::setStopAbort(stopReq->requestInfo, false); - - stopReq->apiTimeout = 5000; - stopReq->transactionTimeout = 1000; - stopReq->readOperationTimeout = 1000; - stopReq->operationTimeout = 1000; - stopReq->senderData = 12; - stopReq->senderRef = _ownReference; - timeOut += stopReq->apiTimeout; - timeOut += stopReq->transactionTimeout; - timeOut += stopReq->readOperationTimeout; - timeOut += stopReq->operationTimeout; - timeOut *= 3; - - m_stopRec.sentCount++; - if(callback == 0) - sendSignal(nodeId, WAIT_STOP, signal, true); - else - sendSignal(nodeId, NO_WAIT, signal, true); - } - } - - if(stopCount != 0) - * stopCount = m_stopRec.sentCount; + int count = 0; - if(callback == 0){ - m_stopRec.inUse = false; - return 0; - // return m_stopRec.reply; - } else { - return 0; - } + SignalSender ss(theFacade); + ss.lock(); // lock will be released on exit - m_stopRec.inUse = false; - return m_stopRec.reply; -} + SimpleSignal ssig; + ResumeReq* const resumeReq = + CAST_PTR(ResumeReq, ssig.getDataPtrSend()); + ssig.set(ss,TestOrd::TraceAPI, NDBCNTR, GSN_RESUME_REQ, + ResumeReq::SignalLength); + resumeReq->senderData = 12; + resumeReq->senderRef = ss.getOwnRef(); -int -MgmtSrvr::exitSingleUser(int * stopCount, bool abort, - ExitSingleCallback callback, void * anyData) -{ - m_stopRec.sentCount = 0; - m_stopRec.reply = 0; - m_stopRec.nodeId = 0; - m_stopRec.anyData = anyData; - m_stopRec.callback = callback; - m_stopRec.inUse = true; - - NodeId nodeId = 0; while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){ if(okToSendTo(nodeId, true) == 0){ - - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } - - ResumeReq* const resumeReq = - CAST_PTR(ResumeReq, signal->getDataPtrSend()); - signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_RESUME_REQ, - StopReq::SignalLength); - resumeReq->senderData = 12; - resumeReq->senderRef = _ownReference; - - m_stopRec.sentCount++; - if(callback == 0) - sendSignal(nodeId, WAIT_STOP, signal, true); - else - sendSignal(nodeId, NO_WAIT, signal, true); + SendStatus result = ss.sendSignal(nodeId, &ssig); + if (result == SEND_OK) + count++; } } - m_stopRec.singleUserMode = false; - if(stopCount != 0) - * stopCount = m_stopRec.sentCount; - - - if(callback == 0){ - m_stopRec.inUse = false; - return m_stopRec.reply; - } else { - return 0; - } + * stopCount = count; - m_stopRec.inUse = false; - return m_stopRec.reply; + return 0; } - /***************************************************************************** * Status ****************************************************************************/ @@ -1444,32 +1189,32 @@ MgmtSrvr::exitSingleUser(int * stopCount, bool abort, #include <ClusterMgr.hpp> int -MgmtSrvr::status(int processId, +MgmtSrvr::status(int nodeId, ndb_mgm_node_status * _status, Uint32 * version, Uint32 * _phase, bool * _system, Uint32 * dynamic, Uint32 * nodegroup, - Uint32 * connectCount) + Uint32 * connectCount, + const char **address) { - if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API || - getNodeType(processId) == NDB_MGM_NODE_TYPE_MGM) { - if(versionNode(processId, false,0,0) ==0) - * version = m_versionRec.version[processId]; - else - * version = 0; + if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API || + getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) { + versionNode(nodeId, *version, address); + } else { + *address= get_connect_address(nodeId); } const ClusterMgr::Node node = - theFacade->theClusterMgr->getNodeInfo(processId); + theFacade->theClusterMgr->getNodeInfo(nodeId); if(!node.connected){ * _status = NDB_MGM_NODE_STATUS_NO_CONTACT; return 0; } - if (getNodeType(processId) == NDB_MGM_NODE_TYPE_NDB) { + if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) { * version = node.m_info.m_version; } @@ -1532,67 +1277,81 @@ MgmtSrvr::status(int processId, } int -MgmtSrvr::setEventReportingLevelImpl(int processId, +MgmtSrvr::setEventReportingLevelImpl(int nodeId, const EventSubscribeReq& ll) { - - int result = okToSendTo(processId, true); - if (result != 0) { - return result; - } - - NdbApiSignal signal(_ownReference); + INIT_SIGNAL_SENDER(ss,nodeId); + SimpleSignal ssig; EventSubscribeReq * dst = - CAST_PTR(EventSubscribeReq, signal.getDataPtrSend()); - - * dst = ll; - - signal.set(TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ, - EventSubscribeReq::SignalLength); - - theFacade->lock_mutex(); - send(&signal, processId, NODE_TYPE_DB); - theFacade->unlock_mutex(); - + CAST_PTR(EventSubscribeReq, ssig.getDataPtrSend()); + ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ, + EventSubscribeReq::SignalLength); + *dst = ll; + + send(ss,ssig,nodeId,NODE_TYPE_DB); + +#if 0 + while (1) + { + SimpleSignal *signal = ss.waitFor(); + int gsn = signal->readSignalNumber(); + switch (gsn) { + case GSN_EVENT_SUBSCRIBE_CONF:{ + break; + } + case GSN_EVENT_SUBSCRIBE_REF:{ + return SEND_OR_RECEIVE_FAILED; + } + case GSN_NF_COMPLETEREP:{ + const NFCompleteRep * const rep = + CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr()); + if (rep->failedNodeId == nodeId) + return SEND_OR_RECEIVE_FAILED; + break; + } + case GSN_NODE_FAILREP:{ + const NodeFailRep * const rep = + CAST_CONSTPTR(NodeFailRep, signal->getDataPtr()); + if (NodeBitmask::get(rep->theNodes,nodeId)) + return SEND_OR_RECEIVE_FAILED; + break; + } + default: + report_unknown_signal(signal); + return SEND_OR_RECEIVE_FAILED; + } + + } +#endif return 0; } //**************************************************************************** //**************************************************************************** int -MgmtSrvr::setNodeLogLevelImpl(int processId, const SetLogLevelOrd & ll) +MgmtSrvr::setNodeLogLevelImpl(int nodeId, const SetLogLevelOrd & ll) { - int result = okToSendTo(processId, true); - if (result != 0) { - return result; - } + INIT_SIGNAL_SENDER(ss,nodeId); - NdbApiSignal signal(_ownReference); - - SetLogLevelOrd * dst = CAST_PTR(SetLogLevelOrd, signal.getDataPtrSend()); - - * dst = ll; - - signal.set(TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD, - SetLogLevelOrd::SignalLength); + SimpleSignal ssig; + ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD, + SetLogLevelOrd::SignalLength); + SetLogLevelOrd* const dst = CAST_PTR(SetLogLevelOrd, ssig.getDataPtrSend()); + *dst = ll; - theFacade->lock_mutex(); - theFacade->sendSignalUnCond(&signal, processId); - theFacade->unlock_mutex(); - - return 0; + return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; } int -MgmtSrvr::send(NdbApiSignal* signal, Uint32 node, Uint32 node_type){ +MgmtSrvr::send(SignalSender &ss, SimpleSignal &ssig, Uint32 node, Uint32 node_type){ Uint32 max = (node == 0) ? MAX_NODES : node + 1; for(; node < max; node++){ while(nodeTypes[node] != (int)node_type && node < max) node++; if(nodeTypes[node] != (int)node_type) break; - theFacade->sendSignalUnCond(signal, node); + ss.sendSignal(node, &ssig); } return 0; } @@ -1601,34 +1360,21 @@ MgmtSrvr::send(NdbApiSignal* signal, Uint32 node, Uint32 node_type){ //**************************************************************************** int -MgmtSrvr::insertError(int processId, int errorNo) +MgmtSrvr::insertError(int nodeId, int errorNo) { if (errorNo < 0) { return INVALID_ERROR_NUMBER; } - int result; - result = okToSendTo(processId, true); - if (result != 0) { - return result; - } + INIT_SIGNAL_SENDER(ss,nodeId); - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } - - TamperOrd* const tamperOrd = CAST_PTR(TamperOrd, signal->getDataPtrSend()); + SimpleSignal ssig; + ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TAMPER_ORD, + TamperOrd::SignalLength); + TamperOrd* const tamperOrd = CAST_PTR(TamperOrd, ssig.getDataPtrSend()); tamperOrd->errorNo = errorNo; - signal->set(TestOrd::TraceAPI, CMVMI, GSN_TAMPER_ORD, - TamperOrd::SignalLength); - result = sendSignal(processId, NO_WAIT, signal, true); - if (result == -1) { - return SEND_OR_RECEIVE_FAILED; - } - - return 0; + return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; } @@ -1637,37 +1383,23 @@ MgmtSrvr::insertError(int processId, int errorNo) //**************************************************************************** int -MgmtSrvr::setTraceNo(int processId, int traceNo) +MgmtSrvr::setTraceNo(int nodeId, int traceNo) { if (traceNo < 0) { return INVALID_TRACE_NUMBER; } - int result; - result = okToSendTo(processId, true); - if (result != 0) { - return result; - } + INIT_SIGNAL_SENDER(ss,nodeId); - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } - - TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend()); + SimpleSignal ssig; + ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); + TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend()); testOrd->clear(); - // Assume TRACE command causes toggling. Not really defined... ? TODO testOrd->setTraceCommand(TestOrd::Toggle, (TestOrd::TraceSpecification)traceNo); - signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); - - result = sendSignal(processId, NO_WAIT, signal, true); - if (result == -1) { - return SEND_OR_RECEIVE_FAILED; - } - return 0; + return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; } //**************************************************************************** @@ -1686,14 +1418,10 @@ MgmtSrvr::getBlockNumber(const BaseString &blockName) //**************************************************************************** int -MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode, +MgmtSrvr::setSignalLoggingMode(int nodeId, LogMode mode, const Vector<BaseString>& blocks) { - int result; - result = okToSendTo(processId, true); - if (result != 0) { - return result; - } + INIT_SIGNAL_SENDER(ss,nodeId); // Convert from MgmtSrvr format... @@ -1728,12 +1456,10 @@ MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode, return -1; } - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } + SimpleSignal ssig; + ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); - TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend()); + TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend()); testOrd->clear(); if (blocks.size() == 0 || blocks[0] == "ALL") { @@ -1743,78 +1469,44 @@ MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode, for(unsigned i = 0; i < blocks.size(); i++){ int blockNumber = getBlockNumber(blocks[i]); if (blockNumber == -1) { - releaseSignal(signal); return INVALID_BLOCK_NAME; } testOrd->addSignalLoggerCommand(blockNumber, command, logSpec); } // for } // else - - signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); - result = sendSignal(processId, NO_WAIT, signal, true); - if (result == -1) { - return SEND_OR_RECEIVE_FAILED; - } - return 0; + return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; } - /***************************************************************************** * Signal tracing *****************************************************************************/ -int MgmtSrvr::startSignalTracing(int processId) +int MgmtSrvr::startSignalTracing(int nodeId) { - int result; - result = okToSendTo(processId, true); - if (result != 0) { - return result; - } - - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } - + INIT_SIGNAL_SENDER(ss,nodeId); - TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend()); + SimpleSignal ssig; + ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); + + TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend()); testOrd->clear(); testOrd->setTestCommand(TestOrd::On); - signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); - result = sendSignal(processId, NO_WAIT, signal, true); - if (result == -1) { - return SEND_OR_RECEIVE_FAILED; - } - - return 0; + return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; } int -MgmtSrvr::stopSignalTracing(int processId) +MgmtSrvr::stopSignalTracing(int nodeId) { - int result; - result = okToSendTo(processId, true); - if (result != 0) { - return result; - } - - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } + INIT_SIGNAL_SENDER(ss,nodeId); - TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend()); + SimpleSignal ssig; + ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); + TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend()); testOrd->clear(); testOrd->setTestCommand(TestOrd::Off); - signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); - result = sendSignal(processId, NO_WAIT, signal, true); - if (result == -1) { - return SEND_OR_RECEIVE_FAILED; - } - - return 0; + return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; } @@ -1823,7 +1515,7 @@ MgmtSrvr::stopSignalTracing(int processId) *****************************************************************************/ int -MgmtSrvr::dumpState(int processId, const char* args) +MgmtSrvr::dumpState(int nodeId, const char* args) { // Convert the space separeted args // string to an int array @@ -1845,29 +1537,20 @@ MgmtSrvr::dumpState(int processId, const char* args) } } - return dumpState(processId, args_array, numArgs); + return dumpState(nodeId, args_array, numArgs); } int -MgmtSrvr::dumpState(int processId, const Uint32 args[], Uint32 no) +MgmtSrvr::dumpState(int nodeId, const Uint32 args[], Uint32 no) { - int result; - - result = okToSendTo(processId, true); - if (result != 0) { - return result; - } - - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } + INIT_SIGNAL_SENDER(ss,nodeId); const Uint32 len = no > 25 ? 25 : no; + SimpleSignal ssig; DumpStateOrd * const dumpOrd = - CAST_PTR(DumpStateOrd, signal->getDataPtrSend()); - signal->set(TestOrd::TraceAPI, CMVMI, GSN_DUMP_STATE_ORD, len); + CAST_PTR(DumpStateOrd, ssig.getDataPtrSend()); + ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_DUMP_STATE_ORD, len); for(Uint32 i = 0; i<25; i++){ if (i < len) dumpOrd->args[i] = args[i]; @@ -1875,12 +1558,7 @@ MgmtSrvr::dumpState(int processId, const Uint32 args[], Uint32 no) dumpOrd->args[i] = 0; } - result = sendSignal(processId, NO_WAIT, signal, true); - if (result == -1) { - return SEND_OR_RECEIVE_FAILED; - } - - return 0; + return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; } @@ -1911,42 +1589,18 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal) int gsn = signal->readSignalNumber(); switch (gsn) { - case GSN_API_VERSION_CONF: { - if (theWaitState == WAIT_VERSION) { - const ApiVersionConf * const conf = - CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr()); - if(m_versionRec.callback != 0) - m_versionRec.callback(conf->nodeId, conf->version, this, 0); - else { - m_versionRec.version[conf->nodeId]=conf->version; - } - } else return; - theWaitState = NO_WAIT; - } - break; - case GSN_EVENT_SUBSCRIBE_CONF: break; - + case GSN_EVENT_SUBSCRIBE_REF: + break; case GSN_EVENT_REP: eventReport(refToNode(signal->theSendersBlockRef), signal->getDataPtr()); break; - case GSN_STOP_REF:{ - const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr()); - const NodeId nodeId = refToNode(signal->theSendersBlockRef); - handleStopReply(nodeId, ref->errorCode); - return; - } + case GSN_NF_COMPLETEREP: break; - - case GSN_MGM_LOCK_CONFIG_REP: - case GSN_MGM_LOCK_CONFIG_REQ: - case GSN_MGM_UNLOCK_CONFIG_REP: - case GSN_MGM_UNLOCK_CONFIG_REQ: { - m_signalRecvQueue.receive(new NdbApiSignal(*signal)); + case GSN_NODE_FAILREP: break; - } default: g_eventLogger.error("Unknown signal received. SignalNumber: " @@ -1961,75 +1615,6 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal) } } -/** - * A database node was either stopped or there was some error - */ -void -MgmtSrvr::handleStopReply(NodeId nodeId, Uint32 errCode) -{ - /** - * If we are in single user mode and get a stop reply from a - * DB node, then we have had a node crash. - * If all DB nodes are gone, and we are still in single user mode, - * the set m_stopRec.singleUserMode = false; - */ - if(m_stopRec.singleUserMode) { - ClusterMgr::Node node; - bool failure = true; - for(Uint32 i = 0; i<MAX_NODES; i++) { - if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) { - node = theFacade->theClusterMgr->getNodeInfo(i); - if((node.m_state.startLevel == NodeState::SL_NOTHING)) - failure = true; - else - failure = false; - } - } - if(failure) { - m_stopRec.singleUserMode = false; - } - } - if(m_stopRec.inUse == false) - return; - - if(!(m_stopRec.nodeId == 0 || m_stopRec.nodeId == nodeId)) - goto error; - - if(m_stopRec.sentCount <= 0) - goto error; - - if(!(theWaitState == WAIT_STOP || m_stopRec.callback != 0)) - goto error; - - if(errCode != 0) - m_stopRec.reply = translateStopRef(errCode); - - m_stopRec.sentCount --; - if(m_stopRec.sentCount == 0){ - if(theWaitState == WAIT_STOP){ - theWaitState = NO_WAIT; - NdbCondition_Signal(theMgmtWaitForResponseCondPtr); - return; - } - if(m_stopRec.callback != 0){ - m_stopRec.inUse = false; - StopCallback callback = m_stopRec.callback; - m_stopRec.callback = NULL; - (* callback)(m_stopRec.nodeId, - m_stopRec.anyData, - m_stopRec.reply); - return; - } - } - return; - - error: - if(errCode != 0){ - g_eventLogger.error("Unexpected signal received. SignalNumber: %i from %d", - GSN_STOP_REF, nodeId); - } -} - void MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete) { @@ -2043,16 +1628,8 @@ MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete) theData[0] = NDB_LE_Disconnected; if(nfComplete) { - handleStopReply(nodeId, 0); DBUG_VOID_RETURN; } - - if(theWaitNode == nodeId && - theWaitState != NO_WAIT && theWaitState != WAIT_STOP) - { - theWaitState = WAIT_NODEFAILURE; - NdbCondition_Signal(theMgmtWaitForResponseCondPtr); - } } eventReport(_ownNodeId, theData); @@ -2401,6 +1978,7 @@ MgmtSrvr::eventReport(NodeId nodeId, const Uint32 * theData) /*************************************************************************** * Backup ***************************************************************************/ + int MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted) { @@ -2415,7 +1993,6 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted) if(!next) return NO_CONTACT_WITH_DB_NODES; SimpleSignal ssig; - BackupReq* req = CAST_PTR(BackupReq, ssig.getDataPtrSend()); ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_BACKUP_REQ, BackupReq::SignalLength); @@ -2430,8 +2007,7 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted) while (1) { if (do_send) { - SendStatus result = ss.sendSignal(nodeId, &ssig); - if (result != SEND_OK) { + if (ss.sendSignal(nodeId, &ssig) != SEND_OK) { return SEND_OR_RECEIVE_FAILED; } if (waitCompleted == 0) @@ -2533,13 +2109,13 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted) return SEND_OR_RECEIVE_FAILED; } } - - return 0; } int MgmtSrvr::abortBackup(Uint32 backupId) { + SignalSender ss(theFacade); + bool next; NodeId nodeId = 0; while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && @@ -2549,25 +2125,17 @@ MgmtSrvr::abortBackup(Uint32 backupId) return NO_CONTACT_WITH_DB_NODES; } - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } + SimpleSignal ssig; - AbortBackupOrd* ord = CAST_PTR(AbortBackupOrd, signal->getDataPtrSend()); - signal->set(TestOrd::TraceAPI, BACKUP, GSN_ABORT_BACKUP_ORD, - AbortBackupOrd::SignalLength); + AbortBackupOrd* ord = CAST_PTR(AbortBackupOrd, ssig.getDataPtrSend()); + ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_ABORT_BACKUP_ORD, + AbortBackupOrd::SignalLength); ord->requestType = AbortBackupOrd::ClientAbort; ord->senderData = 19; ord->backupId = backupId; - int result = sendSignal(nodeId, NO_WAIT, signal, true); - if (result == -1) { - return SEND_OR_RECEIVE_FAILED; - } - - return 0; + return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; } @@ -2582,26 +2150,6 @@ MgmtSrvr::repCommand(Uint32* repReqId, Uint32 request, bool waitCompleted) return 0; } - -NodeId -MgmtSrvr::getPrimaryNode() const { -#if 0 - Uint32 tmp; - const Properties *prop = NULL; - - getConfig()->get("SYSTEM", &prop); - if(prop == NULL) - return 0; - - prop->get("PrimaryMGMNode", &tmp); - - return tmp; -#else - return 0; -#endif -} - - MgmtSrvr::Allocated_resources::Allocated_resources(MgmtSrvr &m) : m_mgmsrv(m) { @@ -2751,7 +2299,6 @@ MgmtSrvr::setDbParameter(int node, int param, const char * value, NdbMutex_Unlock(m_configMutex); return 0; } - int MgmtSrvr::setConnectionDbParameter(int node1, int node2, @@ -2886,10 +2433,6 @@ int MgmtSrvr::set_connect_string(const char *str) } -template class Vector<SigMatch>; -#if __SUNPRO_CC != 0x560 -template bool SignalQueue::waitFor<SigMatch>(Vector<SigMatch>&, SigMatch**, NdbApiSignal**, unsigned); -#endif template class MutexVector<unsigned short>; template class MutexVector<Ndb_mgmd_event_service::Event_listener>; diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp index de1af1286ff..3b14fa60e6b 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.hpp +++ b/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -22,15 +22,17 @@ #include <NdbCondition.h> #include <mgmapi.h> - +#include <NdbTCP.h> +#include <ConfigRetriever.hpp> #include <Vector.hpp> #include <NodeBitmask.hpp> #include <signaldata/ManagementServer.hpp> -#include "SignalQueue.hpp" #include <ndb_version.h> #include <EventLogger.hpp> #include <signaldata/EventSubscribeReq.hpp> +#include <SignalSender.hpp> + /** * @desc Block number for Management server. * @todo This should probably be somewhere else. I don't know where atm. @@ -200,51 +202,26 @@ public: ~MgmtSrvr(); - int status(int processId, - ndb_mgm_node_status * status, + /** + * Get status on a node. + * address may point to a common area (e.g. from inet_addr) + * There is no gaurentee that it is preserved across calls. + * Copy the string if you are not going to use it immediately. + */ + int status(int nodeId, + ndb_mgm_node_status * status, Uint32 * version, Uint32 * phase, bool * systemShutdown, Uint32 * dynamicId, Uint32 * nodeGroup, - Uint32 * connectCount); + Uint32 * connectCount, + const char **address); // All the functions below may return any of this error codes: // NO_CONTACT_WITH_PROCESS, PROCESS_NOT_CONFIGURED, WRONG_PROCESS_TYPE, // COULD_NOT_ALLOCATE_MEMORY, SEND_OR_RECEIVE_FAILED - - typedef void (* StopCallback)(int nodeId, void * anyData, int errorCode); - - typedef void (* VersionCallback)(int nodeId, int version, - void * anyData, int errorCode); - - - typedef void (* EnterSingleCallback)(int nodeId, void * anyData, - int errorCode); - typedef void (* ExitSingleCallback)(int nodeId, void * anyData, - int errorCode); - - /** - * Lock configuration - */ - int lockConf(); - - /** - * Unlock configuration, and commit it if commit is true - */ - int unlockConf(bool commit); - - /** - * Commit new configuration - */ - int commitConfig(); - - /** - * Rollback configuration - */ - int rollbackConfig(); - /** * Save a configuration to permanent storage */ @@ -273,12 +250,12 @@ public: * @param processId: Id of the DB process to stop * @return 0 if succeeded, otherwise: as stated above, plus: */ - int stopNode(int nodeId, bool abort = false, StopCallback = 0, void *any= 0); + int stopNode(int nodeId, bool abort = false); /** * Stop the system */ - int stop(int * cnt = 0, bool abort = false, StopCallback = 0, void *any = 0); + int stop(int * cnt = 0, bool abort = false); /** * print version info about a node @@ -286,27 +263,18 @@ public: * @param processId: Id of the DB process to stop * @return 0 if succeeded, otherwise: as stated above, plus: */ - int versionNode(int nodeId, bool abort = false, - VersionCallback = 0, void *any= 0); + int versionNode(int nodeId, Uint32 &version, const char **address); /** - * print version info about all node in the system - */ - int version(int * cnt = 0, bool abort = false, - VersionCallback = 0, void *any = 0); - - /** * Maintenance on the system */ - int enterSingleUser(int * cnt = 0, Uint32 singleuserNodeId = 0, - EnterSingleCallback = 0, void *any = 0); + int enterSingleUser(int * cnt = 0, Uint32 singleuserNodeId = 0); /** * Resume from maintenance on the system */ - int exitSingleUser(int * cnt = 0, bool abort = false, - ExitSingleCallback = 0, void *any = 0); + int exitSingleUser(int * cnt = 0, bool abort = false); /** * Start DB process. @@ -320,15 +288,14 @@ public: * @param processId: Id of the DB process to start */ int restartNode(int processId, bool nostart, bool initialStart, - bool abort = false, - StopCallback = 0, void * anyData = 0); + bool abort = false); /** * Restart the system */ int restart(bool nostart, bool initialStart, bool abort = false, - int * stopCount = 0, StopCallback = 0, void * anyData = 0); + int * stopCount = 0); struct BackupEvent { enum Event { @@ -483,13 +450,6 @@ public: const Config * getConfig() const; /** - * Change configuration paramter - */ - bool changeConfig(const BaseString §ion, - const BaseString ¶m, - const BaseString &value); - - /** * Returns the node count for the specified node type. * * @param type The node type. @@ -498,11 +458,6 @@ public: int getNodeCount(enum ndb_mgm_node_type type) const; /** - * Returns the nodeId of the management master - */ - NodeId getPrimaryNode() const; - - /** * Returns the port number. * @return port number. */ @@ -528,8 +483,17 @@ public: private: //************************************************************************** - int setEventReportingLevel(int processId, LogLevel::EventCategory, Uint32); - + int send(SignalSender &ss, SimpleSignal &ssig, Uint32 node, Uint32 node_type); + + int sendSTOP_REQ(NodeId nodeId, + NodeBitmask &stoppedNodes, + Uint32 singleUserNodeId, + bool abort, + bool stop, + bool restart, + bool nostart, + bool initialStart); + /** * Check if it is possible to send a signal to a (DB) process * @@ -593,9 +557,6 @@ private: // Returns: - //************************************************************************** - void handle_MGM_LOCK_CONFIG_REQ(NdbApiSignal *signal); - void handle_MGM_UNLOCK_CONFIG_REQ(NdbApiSignal *signal); - //************************************************************************** // Specific signal handling data //************************************************************************** @@ -619,59 +580,8 @@ private: enum WaitSignalType { NO_WAIT, // We don't expect to receive any signal WAIT_SET_VAR, // Accept SET_VAR_CONF and SET_VAR_REF - WAIT_SUBSCRIBE_CONF, // Accept event subscription confirmation - WAIT_STOP, - WAIT_BACKUP_STARTED, - WAIT_BACKUP_COMPLETED, - WAIT_VERSION, - WAIT_NODEFAILURE + WAIT_SUBSCRIBE_CONF // Accept event subscription confirmation }; - - /** - * Get an unused signal - * @return A signal if succeeded, NULL otherwise - */ - NdbApiSignal* getSignal(); - - /** - * Add a signal to the list of unused signals - * @param signal: The signal to add - */ - void releaseSignal(NdbApiSignal* signal); - - /** - * Remove a signal from the list of unused signals and delete - * the memory for it. - */ - void freeSignal(); - - /** - * Send a signal - * @param processId: Id of the receiver process - * @param waitState: State denoting a set of signals we accept to receive - * @param signal: The signal to send - * @return 0 if succeeded, -1 otherwise - */ - int sendSignal(Uint16 processId, WaitSignalType waitState, - NdbApiSignal* signal, bool force = false); - - /** - * Send a signal and wait for an answer signal - * @param processId: Id of the receiver process - * @param waitState: State denoting a set of signals we accept to receive. - * @param signal: The signal to send - * @return 0 if succeeded, -1 otherwise (for example failed to send or - * failed to receive expected signal). - */ - int sendRecSignal(Uint16 processId, WaitSignalType waitState, - NdbApiSignal* signal, bool force = false, - int waitTime = WAIT_FOR_RESPONSE_TIMEOUT); - - /** - * Wait for a signal to arrive. - * @return 0 if signal arrived, -1 otherwise - */ - int receiveOptimisedResponse(int waitTime); /** * This function is called from "outside" of MgmtSrvr @@ -682,7 +592,7 @@ private: static void signalReceivedNotification(void* mgmtSrvr, NdbApiSignal* signal, struct LinearSectionPtr ptr[3]); - + /** * Called from "outside" of MgmtSrvr when a DB process has died. * @param mgmtSrvr: The MgmtSrvr object wreceiveOptimisedResponsehich @@ -719,31 +629,7 @@ private: class TransporterFacade * theFacade; - class SignalQueue m_signalRecvQueue; - - struct StopRecord { - StopRecord(){ inUse = false; callback = 0; singleUserMode = false;} - bool inUse; - bool singleUserMode; - int sentCount; - int reply; - int nodeId; - void * anyData; - StopCallback callback; - }; - StopRecord m_stopRec; - - struct VersionRecord { - VersionRecord(){ inUse = false; callback = 0;} - bool inUse; - Uint32 version[MAX_NODES]; - VersionCallback callback; - }; - VersionRecord m_versionRec; - int sendVersionReq( int processId); - - - void handleStopReply(NodeId nodeId, Uint32 errCode); + int sendVersionReq( int processId, Uint32 &version, const char **address); int translateStopRef(Uint32 errCode); bool _isStopThread; @@ -764,14 +650,8 @@ private: static void *logLevelThread_C(void *); void logLevelThreadRun(); - struct NdbThread *m_signalRecvThread; - static void *signalRecvThread_C(void *); - void signalRecvThreadRun(); - Config *_props; - int send(class NdbApiSignal* signal, Uint32 node, Uint32 node_type); - ConfigRetriever *m_config_retriever; }; diff --git a/ndb/src/mgmsrv/MgmtSrvrConfig.cpp b/ndb/src/mgmsrv/MgmtSrvrConfig.cpp index 6c4b4e9ae3c..e56643a3d7e 100644 --- a/ndb/src/mgmsrv/MgmtSrvrConfig.cpp +++ b/ndb/src/mgmsrv/MgmtSrvrConfig.cpp @@ -23,228 +23,6 @@ #include <ConfigRetriever.hpp> #include <ndb_version.h> -void -MgmtSrvr::handle_MGM_LOCK_CONFIG_REQ(NdbApiSignal *signal) { - NodeId sender = refToNode(signal->theSendersBlockRef); - const MgmLockConfigReq * const req = CAST_CONSTPTR(MgmLockConfigReq, signal->getDataPtr()); - - NdbApiSignal *reply = getSignal(); - if(signal == NULL) - return; /** @todo handle allocation failure */ - - reply->set(TestOrd::TraceAPI, - MGMSRV, - GSN_MGM_LOCK_CONFIG_REP, - MgmLockConfigRep::SignalLength); - - MgmLockConfigRep *lockRep = CAST_PTR(MgmLockConfigRep, reply->getDataPtrSend()); - - lockRep->errorCode = MgmLockConfigRep::UNKNOWN_ERROR; - - if(req->newConfigGeneration < m_nextConfigGenerationNumber) { - lockRep->errorCode = MgmLockConfigRep::GENERATION_MISMATCH; - goto done; - } - NdbMutex_Lock(m_configMutex); - - m_nextConfigGenerationNumber = req->newConfigGeneration+1; - - lockRep->errorCode = MgmLockConfigRep::OK; - - done: - sendSignal(sender, NO_WAIT, reply, true); - NdbMutex_Unlock(m_configMutex); - return; -} - -void -MgmtSrvr::handle_MGM_UNLOCK_CONFIG_REQ(NdbApiSignal *signal) { - NodeId sender = refToNode(signal->theSendersBlockRef); - const MgmUnlockConfigReq * const req = CAST_CONSTPTR(MgmUnlockConfigReq, signal->getDataPtr()); - MgmUnlockConfigRep *unlockRep; - - NdbApiSignal *reply = getSignal(); - if(signal == NULL) - goto error; /** @todo handle allocation failure */ - - reply->set(TestOrd::TraceAPI, - MGMSRV, - GSN_MGM_UNLOCK_CONFIG_REP, - MgmUnlockConfigRep::SignalLength); - - unlockRep = CAST_PTR(MgmUnlockConfigRep, reply->getDataPtrSend()); - - unlockRep->errorCode = MgmUnlockConfigRep::UNKNOWN_ERROR; - - - NdbMutex_Lock(m_configMutex); - - if(req->commitConfig == 1) { - m_newConfig = fetchConfig(); - commitConfig(); - } else - rollbackConfig(); - - unlockRep->errorCode = MgmUnlockConfigRep::OK; - - sendSignal(sender, NO_WAIT, reply, true); - error: - NdbMutex_Unlock(m_configMutex); - return; -} - - -/** - * Prepare all MGM nodes for configuration changes - * - * @returns 0 on success, or -1 on failure - */ -int -MgmtSrvr::lockConf() { - int result = -1; - MgmLockConfigReq* lockReq; - NodeId node = 0; - - /* Check if this is the master node */ - if(getPrimaryNode() != _ownNodeId) - goto done; - - if(NdbMutex_Trylock(m_configMutex) != 0) - return -1; - - m_newConfig = new Config(*_config); /* copy the existing config */ - _config = m_newConfig; - - m_newConfig = new Config(*_config); - - m_nextConfigGenerationNumber++; - - /* Make sure the new configuration _always_ is at least one step older */ - if(m_nextConfigGenerationNumber < m_newConfig->getGenerationNumber()+1) - m_nextConfigGenerationNumber = _config->getGenerationNumber()+1; - - m_newConfig->setGenerationNumber(m_nextConfigGenerationNumber); - - node = 0; - while(getNextNodeId(&node, NDB_MGM_NODE_TYPE_MGM)) { - if(node != _ownNodeId) { - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - result = COULD_NOT_ALLOCATE_MEMORY; - goto done; - } - - lockReq = CAST_PTR(MgmLockConfigReq, signal->getDataPtrSend()); - signal->set(TestOrd::TraceAPI, - MGMSRV, - GSN_MGM_LOCK_CONFIG_REQ, - MgmLockConfigReq::SignalLength); - - lockReq->newConfigGeneration = m_nextConfigGenerationNumber; - - result = sendSignal(node, NO_WAIT, signal, true); - - NdbApiSignal *reply = - m_signalRecvQueue.waitFor(GSN_MGM_LOCK_CONFIG_REP, 0); - - if(reply == NULL) { - /** @todo handle timeout/error */ - ndbout << __FILE__ << ":" << __LINE__ << endl; - result = -1; - goto done; - } - - } - } - - done: - NdbMutex_Unlock(m_configMutex); - return result; -} - -/** - * Unlocks configuration - * - * @returns 0 on success, ! 0 on error - */ -int -MgmtSrvr::unlockConf(bool commit) { - int result = -1; - MgmUnlockConfigReq* unlockReq; - NodeId node = 0; - - /* Check if this is the master node */ - if(getPrimaryNode() != _ownNodeId) - goto done; - - errno = 0; - if(NdbMutex_Lock(m_configMutex) != 0) - return -1; - - if(commit) - commitConfig(); - else - rollbackConfig(); - - node = 0; - while(getNextNodeId(&node, NDB_MGM_NODE_TYPE_MGM)) { - if(node != _ownNodeId) { - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - result = COULD_NOT_ALLOCATE_MEMORY; - goto done; - } - - unlockReq = CAST_PTR(MgmUnlockConfigReq, signal->getDataPtrSend()); - signal->set(TestOrd::TraceAPI, - MGMSRV, - GSN_MGM_UNLOCK_CONFIG_REQ, - MgmUnlockConfigReq::SignalLength); - unlockReq->commitConfig = commit; - - result = sendSignal(node, NO_WAIT, signal, true); - - NdbApiSignal *reply = - m_signalRecvQueue.waitFor(GSN_MGM_UNLOCK_CONFIG_REP, 0); - - if(reply == NULL) { - /** @todo handle timeout/error */ - result = -1; - goto done; - } - - } - } - - done: - NdbMutex_Unlock(m_configMutex); - return result; -} - -/** - * Commit the new configuration - */ -int -MgmtSrvr::commitConfig() { - int ret = saveConfig(m_newConfig); - delete _config; - _config = m_newConfig; - m_newConfig = NULL; - ndbout << "commit " << ret << endl; - return ret; -} - -/** - * Rollback to the old configuration - */ -int -MgmtSrvr::rollbackConfig() { - delete m_newConfig; - m_newConfig = NULL; - ndbout << "rollback" << endl; - return saveConfig(_config); -} - /** * Save a configuration to the running configuration file */ @@ -274,7 +52,15 @@ Config * MgmtSrvr::readConfig() { Config *conf; InitConfigFileParser parser; - conf = parser.parseConfig(m_configFilename.c_str()); + if (m_configFilename.length()) + { + conf = parser.parseConfig(m_configFilename.c_str()); + } + else + { + ndbout_c("Reading cluster configuration using my.cnf"); + conf = parser.parse_mycnf(); + } return conf; } @@ -288,12 +74,3 @@ MgmtSrvr::fetchConfig() { } return 0; } - -bool -MgmtSrvr::changeConfig(const BaseString §ion, - const BaseString ¶m, - const BaseString &value) { - if(m_newConfig == NULL) - return false; - return m_newConfig->change(section, param, value); -} diff --git a/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp b/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp index f93948abc75..c99936e1861 100644 --- a/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp +++ b/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp @@ -20,123 +20,3 @@ // Some kind of reuse should be preferred. //****************************************************************************** -#include "MgmtSrvr.hpp" -#include <NdbApiSignal.hpp> -#include <NdbTick.h> - - -NdbApiSignal* -MgmtSrvr::getSignal() -{ - NdbApiSignal* tSignal; - tSignal = theSignalIdleList; - if (tSignal != NULL){ - NdbApiSignal* tSignalNext = tSignal->next(); - tSignal->next(NULL); - theSignalIdleList = tSignalNext; - return tSignal; - } else - { - tSignal = new NdbApiSignal(_ownReference); - if (tSignal != NULL) - tSignal->next(NULL); - } - return tSignal; -} - - -void -MgmtSrvr::releaseSignal(NdbApiSignal* aSignal) -{ - aSignal->next(theSignalIdleList); - theSignalIdleList = aSignal; -} - - -void -MgmtSrvr::freeSignal() -{ - NdbApiSignal* tSignal = theSignalIdleList; - theSignalIdleList = tSignal->next(); - delete tSignal; -} - - -int -MgmtSrvr::sendSignal(Uint16 aNodeId, - WaitSignalType aWaitState, - NdbApiSignal* aSignal, - bool force) -{ - int tReturnCode; - theFacade->lock_mutex(); - if(force){ - tReturnCode = theFacade->sendSignalUnCond(aSignal, - aNodeId); - } else { - tReturnCode = theFacade->sendSignal(aSignal, - aNodeId); - } - releaseSignal(aSignal); - if (tReturnCode == -1) { - theFacade->unlock_mutex(); - return -1; - } - theWaitState = aWaitState; - theFacade->unlock_mutex(); - return 0; -} - - -int -MgmtSrvr::sendRecSignal(Uint16 aNodeId, - WaitSignalType aWaitState, - NdbApiSignal* aSignal, - bool force, - int waitTime) -{ - int tReturnCode; - theFacade->lock_mutex(); - if(force){ - tReturnCode = theFacade->sendSignalUnCond(aSignal, aNodeId); - } else { - tReturnCode = theFacade->sendSignalUnCond(aSignal, aNodeId); - } - releaseSignal(aSignal); - if (tReturnCode == -1) { - theFacade->unlock_mutex(); - return -1; - } - theWaitState = aWaitState; - theWaitNode = aNodeId; - return receiveOptimisedResponse(waitTime); -} - - -int -MgmtSrvr::receiveOptimisedResponse(int waitTime) -{ - int tResultCode; - theFacade->checkForceSend(_blockNumber); - NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime; - - while (theWaitState != NO_WAIT && theWaitState != WAIT_NODEFAILURE - && waitTime > 0) { - NdbCondition_WaitTimeout(theMgmtWaitForResponseCondPtr, - theFacade->theMutexPtr, - waitTime); - if(theWaitState == NO_WAIT || theWaitState == WAIT_NODEFAILURE) - break; - waitTime = (maxTime - NdbTick_CurrentMillisecond()); - }//while - - if(theWaitState == NO_WAIT) { - tResultCode = 0; - } else { - tResultCode = -1; - } - theFacade->unlock_mutex(); - return tResultCode; -} - - diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index ed32ab9c963..8c087c2a3ca 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -222,21 +222,6 @@ ParserRow<MgmApiSession> commands[] = { MGM_ARG("level", Int, Mandatory, "Severety level"), MGM_ARG("enable", Int, Mandatory, "1=disable, 0=enable, -1=toggle"), - MGM_CMD("config lock", &MgmApiSession::configLock, ""), - - MGM_CMD("config unlock", &MgmApiSession::configUnlock, ""), - MGM_ARG("commit", Int, Mandatory, "Commit changes"), - - MGM_CMD("config change", &MgmApiSession::configChange, ""), - MGM_ARG("section", String, Mandatory, "Section"), - MGM_ARG("parameter", String, Mandatory, "Parameter"), - MGM_ARG("value", String, Mandatory, "Value"), - - MGM_CMD("config lock", &MgmApiSession::configLock, ""), - - MGM_CMD("config unlock", &MgmApiSession::configUnlock, ""), - MGM_ARG("commit", Int, Mandatory, "Commit changes"), - MGM_CMD("set parameter", &MgmApiSession::setParameter, ""), MGM_ARG("node", String, Mandatory, "Node"), MGM_ARG("parameter", String, Mandatory, "Parameter"), @@ -940,8 +925,10 @@ printNodeStatus(OutputStream *output, nodeGroup = 0, connectCount = 0; bool system; - mgmsrv.status(nodeId, &status, &version, &startPhase, - &system, &dynamicId, &nodeGroup, &connectCount); + const char *address= NULL; + mgmsrv.status(nodeId, &status, &version, &startPhase, + &system, &dynamicId, &nodeGroup, &connectCount, + &address); output->println("node.%d.type: %s", nodeId, ndb_mgm_get_node_type_string(type)); @@ -953,7 +940,7 @@ printNodeStatus(OutputStream *output, output->println("node.%d.dynamic_id: %d", nodeId, dynamicId); output->println("node.%d.node_group: %d", nodeId, nodeGroup); output->println("node.%d.connect_count: %d", nodeId, connectCount); - output->println("node.%d.address: %s", nodeId, mgmsrv.get_connect_address(nodeId)); + output->println("node.%d.address: %s", nodeId, address); } } @@ -1222,42 +1209,6 @@ MgmApiSession::setLogFilter(Parser_t::Context &ctx, m_output->println(""); } -void -MgmApiSession::configLock(Parser_t::Context &, - Properties const &) { - int ret = m_mgmsrv.lockConf(); - m_output->println("config lock reply"); - m_output->println("result: %d", ret); - m_output->println(""); -} - -void -MgmApiSession::configUnlock(Parser_t::Context &, - Properties const &args) { - Uint32 commit; - args.get("commit", &commit); - int ret = m_mgmsrv.unlockConf(commit == 1); - m_output->println("config unlock reply"); - m_output->println("result: %d", ret); - m_output->println(""); -} - -void -MgmApiSession::configChange(Parser_t::Context &, - Properties const &args) { - BaseString section, param, value; - args.get("section", section); - args.get("parameter", param); - args.get("value", value); - - int ret = m_mgmsrv.changeConfig(section.c_str(), - param.c_str(), - value.c_str()); - m_output->println("config change reply"); - m_output->println("result: %d", ret); - m_output->println(""); -} - static NdbOut& operator<<(NdbOut& out, const LogLevel & ll) { diff --git a/ndb/src/mgmsrv/Services.hpp b/ndb/src/mgmsrv/Services.hpp index ff9008b05a8..431126a1f35 100644 --- a/ndb/src/mgmsrv/Services.hpp +++ b/ndb/src/mgmsrv/Services.hpp @@ -83,9 +83,6 @@ public: void setClusterLogLevel(Parser_t::Context &ctx, const class Properties &args); void setLogFilter(Parser_t::Context &ctx, const class Properties &args); - void configLock(Parser_t::Context &ctx, const class Properties &args); - void configUnlock(Parser_t::Context &ctx, const class Properties &args); - void configChange(Parser_t::Context &ctx, const class Properties &args); void setParameter(Parser_t::Context &ctx, const class Properties &args); void setConnectionParameter(Parser_t::Context &ctx, diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp index ec20101493e..f0c2ac298a5 100644 --- a/ndb/src/mgmsrv/main.cpp +++ b/ndb/src/mgmsrv/main.cpp @@ -102,6 +102,7 @@ static int opt_daemon; // NOT bool, bool need not be int static int opt_non_interactive; static int opt_interactive; static const char * opt_config_filename= 0; +static int opt_mycnf = 0; struct MgmGlobals { MgmGlobals(); @@ -166,6 +167,10 @@ static struct my_option my_long_options[] = "Don't run as daemon, but don't read from stdin", (gptr*) &opt_non_interactive, (gptr*) &opt_non_interactive, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, + { "mycnf", 256, + "Read cluster config from my.cnf", + (gptr*) &opt_mycnf, (gptr*) &opt_mycnf, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -199,7 +204,7 @@ int main(int argc, char** argv) #endif global_mgmt_server_check = 1; - + const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 }; load_defaults("my",load_default_groups,&argc,&argv); @@ -217,13 +222,26 @@ int main(int argc, char** argv) opt_daemon= 0; } + if (opt_mycnf && opt_config_filename) + { + ndbout_c("Both --mycnf and -f is not supported"); + return 0; + } + + if (opt_mycnf == 0 && opt_config_filename == 0) + { + struct stat buf; + if (stat("config.ini", &buf) != -1) + opt_config_filename = "config.ini"; + } + glob->socketServer = new SocketServer(); MgmApiService * mapi = new MgmApiService(); glob->mgmObject = new MgmtSrvr(glob->socketServer, - opt_config_filename, - opt_connect_str); + opt_config_filename, + opt_connect_str); if (g_print_full_config) goto the_end; diff --git a/ndb/tools/ndb_config.cpp b/ndb/tools/ndb_config.cpp index 290dd440479..1b9a771f243 100644 --- a/ndb/tools/ndb_config.cpp +++ b/ndb/tools/ndb_config.cpp @@ -42,6 +42,8 @@ static const char * g_type = 0; static const char * g_host = 0; static const char * g_field_delimiter=","; static const char * g_row_delimiter=" "; +static const char * g_config_file = 0; +static int g_mycnf = 0; int g_print_full_config, opt_ndb_shm; my_bool opt_core; @@ -92,6 +94,12 @@ static struct my_option my_long_options[] = { "rows", 'r', "Row separator", (gptr*) &g_row_delimiter, (gptr*) &g_row_delimiter, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { "config-file", 256, "Path to config.ini", + (gptr*) &g_config_file, (gptr*) &g_config_file, + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { "mycnf", 256, "Read config from my.cnf", + (gptr*) &g_mycnf, (gptr*) &g_mycnf, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -126,7 +134,7 @@ struct Match { int m_key; BaseString m_value; - virtual int eval(NdbMgmHandle, const Iter&); + virtual int eval(const Iter&); }; struct HostMatch : public Match @@ -139,18 +147,21 @@ struct Apply Apply() {} Apply(int val) { m_key = val;} int m_key; - virtual int apply(NdbMgmHandle, const Iter&); + virtual int apply(const Iter&); }; struct NodeTypeApply : public Apply { - virtual int apply(NdbMgmHandle, const Iter&); + virtual int apply(const Iter&); }; static int parse_query(Vector<Apply*>&, int &argc, char**& argv); static int parse_where(Vector<Match*>&, int &argc, char**& argv); -static int eval(NdbMgmHandle, const Iter&, const Vector<Match*>&); -static int apply(NdbMgmHandle, const Iter&, const Vector<Apply*>&); +static int eval(const Iter&, const Vector<Match*>&); +static int apply(const Iter&, const Vector<Apply*>&); +static ndb_mgm_configuration* fetch_configuration(); +static ndb_mgm_configuration* load_configuration(); + int main(int argc, char** argv){ NDB_INIT(argv[0]); @@ -161,51 +172,16 @@ main(int argc, char** argv){ ndb_std_get_one_option))) return -1; - NdbMgmHandle mgm = ndb_mgm_create_handle(); - if(mgm == NULL) { - fprintf(stderr, "Cannot create handle to management server.\n"); - exit(-1); - } + ndb_mgm_configuration * conf = 0; - ndb_mgm_set_error_stream(mgm, stderr); - - if (ndb_mgm_set_connectstring(mgm, g_connectstring)) - { - fprintf(stderr, "* %5d: %s\n", - ndb_mgm_get_latest_error(mgm), - ndb_mgm_get_latest_error_msg(mgm)); - fprintf(stderr, - "* %s", ndb_mgm_get_latest_error_desc(mgm)); - exit(-1); - } + if (g_config_file || g_mycnf) + conf = load_configuration(); + else + conf = fetch_configuration(); - if(ndb_mgm_connect(mgm, try_reconnect-1, 5, 1)) + if (conf == 0) { - fprintf(stderr, "Connect failed"); - fprintf(stderr, " code: %d, msg: %s\n", - ndb_mgm_get_latest_error(mgm), - ndb_mgm_get_latest_error_msg(mgm)); - exit(-1); - } - else if(g_verbose) - { - fprintf(stderr, "Connected to %s:%d\n", - ndb_mgm_get_connected_host(mgm), - ndb_mgm_get_connected_port(mgm)); - } - - ndb_mgm_configuration * conf = ndb_mgm_get_configuration(mgm, 0); - if(conf == 0) - { - fprintf(stderr, "Could not get configuration"); - fprintf(stderr, "code: %d, msg: %s\n", - ndb_mgm_get_latest_error(mgm), - ndb_mgm_get_latest_error_msg(mgm)); - exit(-1); - } - else if(g_verbose) - { - fprintf(stderr, "Fetched configuration\n"); + return -1; } Vector<Apply*> select_list; @@ -231,12 +207,12 @@ main(int argc, char** argv){ iter.first(); for(iter.first(); iter.valid(); iter.next()) { - if(eval(mgm, iter, where_clause)) + if(eval(iter, where_clause)) { if(prev) printf("%s", g_row_delimiter); prev= true; - apply(mgm, iter, select_list); + apply(iter, select_list); } } printf("\n"); @@ -331,11 +307,11 @@ template class Vector<Match*>; static int -eval(NdbMgmHandle mgm, const Iter& iter, const Vector<Match*>& where) +eval(const Iter& iter, const Vector<Match*>& where) { for(unsigned i = 0; i<where.size(); i++) { - if(where[i]->eval(mgm, iter) == 0) + if(where[i]->eval(iter) == 0) return 0; } @@ -344,11 +320,11 @@ eval(NdbMgmHandle mgm, const Iter& iter, const Vector<Match*>& where) static int -apply(NdbMgmHandle mgm, const Iter& iter, const Vector<Apply*>& list) +apply(const Iter& iter, const Vector<Apply*>& list) { for(unsigned i = 0; i<list.size(); i++) { - list[i]->apply(mgm, iter); + list[i]->apply(iter); if(i + 1 != list.size()) printf("%s", g_field_delimiter); } @@ -356,19 +332,19 @@ apply(NdbMgmHandle mgm, const Iter& iter, const Vector<Apply*>& list) } int -Match::eval(NdbMgmHandle h, const Iter& iter) +Match::eval(const Iter& iter) { Uint32 val32; Uint64 val64; const char* valc; if (iter.get(m_key, &val32) == 0) { - if(atoi(m_value.c_str()) != val32) + if(atoi(m_value.c_str()) != (int)val32) return 0; } else if(iter.get(m_key, &val64) == 0) { - if(strtoll(m_value.c_str(), (char **)NULL, 10) != val64) + if(strtoll(m_value.c_str(), (char **)NULL, 10) != (long long)val64) return 0; } else if(iter.get(m_key, &valc) == 0) @@ -418,7 +394,7 @@ HostMatch::eval(NdbMgmHandle h, const Iter& iter) } int -Apply::apply(NdbMgmHandle h, const Iter& iter) +Apply::apply(const Iter& iter) { Uint32 val32; Uint64 val64; @@ -439,7 +415,7 @@ Apply::apply(NdbMgmHandle h, const Iter& iter) } int -NodeTypeApply::apply(NdbMgmHandle h, const Iter& iter) +NodeTypeApply::apply(const Iter& iter) { Uint32 val32; if (iter.get(CFG_TYPE_OF_SECTION, &val32) == 0) @@ -448,3 +424,86 @@ NodeTypeApply::apply(NdbMgmHandle h, const Iter& iter) } return 0; } + +ndb_mgm_configuration* +fetch_configuration() +{ + ndb_mgm_configuration* conf = 0; + NdbMgmHandle mgm = ndb_mgm_create_handle(); + if(mgm == NULL) { + fprintf(stderr, "Cannot create handle to management server.\n"); + return 0; + } + + ndb_mgm_set_error_stream(mgm, stderr); + + if (ndb_mgm_set_connectstring(mgm, g_connectstring)) + { + fprintf(stderr, "* %5d: %s\n", + ndb_mgm_get_latest_error(mgm), + ndb_mgm_get_latest_error_msg(mgm)); + fprintf(stderr, + "* %s", ndb_mgm_get_latest_error_desc(mgm)); + goto noconnect; + } + + if(ndb_mgm_connect(mgm, try_reconnect-1, 5, 1)) + { + fprintf(stderr, "Connect failed"); + fprintf(stderr, " code: %d, msg: %s\n", + ndb_mgm_get_latest_error(mgm), + ndb_mgm_get_latest_error_msg(mgm)); + goto noconnect; + } + else if(g_verbose) + { + fprintf(stderr, "Connected to %s:%d\n", + ndb_mgm_get_connected_host(mgm), + ndb_mgm_get_connected_port(mgm)); + } + + conf = ndb_mgm_get_configuration(mgm, 0); + if(conf == 0) + { + fprintf(stderr, "Could not get configuration"); + fprintf(stderr, "code: %d, msg: %s\n", + ndb_mgm_get_latest_error(mgm), + ndb_mgm_get_latest_error_msg(mgm)); + } + else if(g_verbose) + { + fprintf(stderr, "Fetched configuration\n"); + } + + ndb_mgm_disconnect(mgm); +noconnect: + ndb_mgm_destroy_handle(&mgm); + + return conf; +} + +#include <Config.hpp> + +ndb_mgm_configuration* +load_configuration() +{ + InitConfigFileParser parser(stderr); + if (g_config_file) + { + if (g_verbose) + fprintf(stderr, "Using config.ini : %s", g_config_file); + + Config* conf = parser.parseConfig(g_config_file); + if (conf) + return conf->m_configValues; + } + + if (g_verbose) + fprintf(stderr, "Using my.cnf"); + + Config* conf = parser.parse_mycnf(); + if (conf) + return conf->m_configValues; + + return 0; +} diff --git a/ndb/tools/ndb_size.pl b/ndb/tools/ndb_size.pl new file mode 100644 index 00000000000..64a20423636 --- /dev/null +++ b/ndb/tools/ndb_size.pl @@ -0,0 +1,263 @@ +#!/usr/bin/perl -w + +use strict; + +use DBI; +use POSIX; +use HTML::Template; + +# MySQL Cluster size estimator +# ---------------------------- +# +# (C)2005 MySQL AB +# +# +# The purpose of this tool is to work out storage requirements +# from an existing MySQL database. +# +# This involves connecting to a mysql server and throwing a bunch +# of queries at it. +# +# We currently estimate sizes for: 4.1, 5.0 and 5.1 to various amounts +# of accurracy. +# +# There is no warranty. +# +# BUGS +# ---- +# - enum/set is 0 byte storage! Woah - efficient! +# - some float stores come out weird (when there's a comma e.g. 'float(4,1)') +# - no disk data values +# - computes the storage requirements of views (and probably MERGE) +# - ignores character sets. + +my $template = HTML::Template->new(filename => 'ndb_size.tmpl', + die_on_bad_params => 0); + +my $dbh; + +{ + my $database= $ARGV[0]; + my $hostname= $ARGV[1]; + my $port= $ARGV[2]; + my $user= $ARGV[3]; + my $password= $ARGV[4]; + my $dsn = "DBI:mysql:database=$database;host=$hostname;port=$port"; + $dbh= DBI->connect($dsn, $user, $password); + $template->param(db => $database); + $template->param(dsn => $dsn); +} + +my @releases = ({rel=>'4.1'},{rel=>'5.0'},{rel=>'5.1'}); +$template->param(releases => \@releases); + +my $tables = $dbh->selectall_arrayref("show tables"); + +my @table_size; + +sub align { + my($to,@unaligned) = @_; + my @aligned; + foreach my $x (@unaligned) { + push @aligned, $to * POSIX::floor(($x+$to-1)/$to); + } + return @aligned; +} + +foreach(@{$tables}) +{ + my $table= @{$_}[0]; + my @columns; + my $info= $dbh->selectall_hashref("describe ".$dbh->quote($table),"Field"); + my @count = $dbh->selectrow_array("select count(*) from " + .$dbh->quote($table)); + my %columnsize; # used for index calculations + + # We now work out the DataMemory usage + + # sizes for 4.1, 5.0, 5.1 + my @totalsize= (0,0,0); + + foreach(keys %$info) + { + my @realsize = (0,0,0); + my $type; + my $size; + my $name= $_; + + if($$info{$_}{Type} =~ /^(.*?)\((\d+)\)/) + { + $type= $1; + $size= $2; + } + else + { + $type= $$info{$_}{Type}; + } + + if($type =~ /tinyint/) + {@realsize=(1,1,1)} + elsif($type =~ /smallint/) + {@realsize=(2,2,2)} + elsif($type =~ /mediumint/) + {@realsize=(3,3,3)} + elsif($type =~ /bigint/) + {@realsize=(8,8,8)} + elsif($type =~ /int/) + {@realsize=(4,4,4)} + elsif($type =~ /float/) + { + if($size<=24) + {@realsize=(4,4,4)} + else + {@realsize=(8,8,8)} + } + elsif($type =~ /double/ || $type =~ /real/) + {@realsize=(8,8,8)} + elsif($type =~ /bit/) + { + my $a=($size+7)/8; + @realsize = ($a,$a,$a); + } + elsif($type =~ /datetime/) + {@realsize=(8,8,8)} + elsif($type =~ /timestamp/) + {@realsize=(4,4,4)} + elsif($type =~ /date/ || $type =~ /time/) + {@realsize=(3,3,3)} + elsif($type =~ /year/) + {@realsize=(1,1,1)} + elsif($type =~ /varchar/ || $type =~ /varbinary/) + { + my $fixed= 1+$size; + my @dynamic=$dbh->selectrow_array("select avg(length(" + .$dbh->quote($name) + .")) from ".$dbh->quote($table)); + $dynamic[0]=0 if !$dynamic[0]; + @realsize= ($fixed,$fixed,ceil($dynamic[0])); + } + elsif($type =~ /binary/ || $type =~ /char/) + {@realsize=($size,$size,$size)} + elsif($type =~ /text/ || $type =~ /blob/) + {@realsize=(256,256,1)} # FIXME check if 5.1 is correct + + @realsize= align(4,@realsize); + + $totalsize[$_]+=$realsize[$_] foreach 0..$#totalsize; + + my @realout; + push @realout,{val=>$_} foreach @realsize; + + push @columns, { + name=>$name, + type=>$type, + size=>$size, + key=>$$info{$_}{Key}, + datamemory=>\@realout, + }; + + $columnsize{$name}= \@realsize; # used for index calculations + } + + # And now... the IndexMemory usage. + # + # Firstly, we assemble some information about the indexes. + # We use SHOW INDEX instead of using INFORMATION_SCHEMA so + # we can still connect to pre-5.0 mysqlds. + my %indexes; + { + my $sth= $dbh->prepare("show index from "$dbh->quote($table)); + $sth->execute; + while(my $i = $sth->fetchrow_hashref) + { + $indexes{${%$i}{Key_name}}= { + type=>${%$i}{Index_type}, + unique=>!${%$i}{Non_unique}, + comment=>${%$i}{Comment}, + } if !defined($indexes{${%$i}{Key_name}}); + + $indexes{${%$i}{Key_name}}{columns}[${%$i}{Seq_in_index}-1]= + ${%$i}{Column_name}; + } + } + + if(!defined($indexes{PRIMARY})) { + $indexes{PRIMARY}= { + type=>'BTREE', + unique=>1, + comment=>'Hidden pkey created by NDB', + columns=>['HIDDEN_NDB_PKEY'], + }; + push @columns, { + name=>'HIDDEN_NDB_PKEY', + type=>'bigint', + size=>8, + key=>'PRI', + datamemory=>[{val=>8},{val=>8},{val=>8}], + }; + $columnsize{'HIDDEN_NDB_PKEY'}= [8,8,8]; + } + + my @IndexDataMemory= ({val=>0},{val=>0},{val=>0}); + my @RowIndexMemory= ({val=>0},{val=>0},{val=>0}); + + my @indexes; + foreach my $index (keys %indexes) { + my $im41= 25; + $im41+=$columnsize{$_}[0] foreach @{$indexes{$index}{columns}}; + my @im = ({val=>$im41},{val=>25},{val=>25}); + my @dm = ({val=>10},{val=>10},{val=>10}); + push @indexes, { + name=>$index, + type=>$indexes{$index}{type}, + columns=>join(',',@{$indexes{$index}{columns}}), + indexmemory=>\@im, + datamemory=>\@dm, + }; + $IndexDataMemory[$_]{val}+=$dm[$_]{val} foreach 0..2; + $RowIndexMemory[$_]{val}+=$im[$_]{val} foreach 0..2; + } + + # total size + 16 bytes overhead + my @TotalDataMemory; + $TotalDataMemory[$_]{val}=$IndexDataMemory[$_]{val}+$totalsize[$_]+16 foreach 0..2; + + my @RowDataMemory; + push @RowDataMemory,{val=>$_} foreach @totalsize; + + my @RowPerPage; + push @RowPerPage,{val=>(floor((32768-128)/$TotalDataMemory[$_]{val}))} foreach 0..$#TotalDataMemory; + + my @RowPerIndexPage; + push @RowPerIndexPage,{val=>(floor(8192/$RowIndexMemory[$_]{val}))} foreach 0..$#TotalDataMemory; + + my @DataMemory; + push @DataMemory,{val=>ceil(($count[0]/($RowPerPage[$_]{val})))*32} foreach 0..$#RowPerPage; + + my @IndexMemory; + push @IndexMemory,{val=>ceil(($count[0]/($RowPerIndexPage[$_]{val})))*8} foreach 0..$#RowPerPage; + + my $count= $count[0]; + my @counts; + $counts[$_]{val}= $count foreach 0..$#releases; + + push @table_size, { + table=>$table, + indexes=>\@indexes, + columns=>\@columns, + count=>\@counts, + RowDataMemory=>\@RowDataMemory, + releases=>\@releases, + IndexDataMemory=>\@IndexDataMemory, + TotalDataMemory=>\@TotalDataMemory, + RowPerPage=>\@RowPerPage, + DataMemory=>\@DataMemory, + RowIndexMemory=>\@RowIndexMemory, + RowPerIndexPage=>\@RowPerIndexPage, + IndexMemory=>\@IndexMemory, + + }; +} + +$template->param(tables => \@table_size); +print $template->output; diff --git a/ndb/tools/ndb_size.tmpl b/ndb/tools/ndb_size.tmpl new file mode 100644 index 00000000000..d83d5d2c6af --- /dev/null +++ b/ndb/tools/ndb_size.tmpl @@ -0,0 +1,175 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> + <head> + <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8"/> + <meta name="keywords" content="MySQL Cluster" /> + <title>MySQL Cluster size estimate for <TMPL_VAR NAME="db" ESCAPE="HTML"></title> +<style type="text/css"> +table { border-collapse: collapse } +td,th { border: 1px solid black } +</style> + </head> +<body> +<h1>MySQL Cluster analysis for <TMPL_VAR NAME="db" escape="html"></h1> +<p>This is an automated analysis of the <TMPL_VAR NAME="DSN" escape="html"> database for migration into <a href="http://www.mysql.com/">MySQL</a> Cluster. No warranty is made to the accuracy of the information.</p> + +<p>This information should be valid for MySQL 4.1</p> + +<ul> +<TMPL_LOOP NAME="tables"> +<li><TMPL_VAR NAME="table"></li> +</TMPL_LOOP> +</ul> + +<hr/> + +<TMPL_LOOP NAME="tables"> +<h2><TMPL_VAR NAME="table"></h2> +<table> + <tr> + <th>Column</th> + <th>Type</th> + <th>Size</th> + <th>Key</th> + <TMPL_LOOP NAME=releases> + <th><TMPL_VAR NAME=rel> NDB Size</th> + </TMPL_LOOP> + </tr> + <TMPL_LOOP NAME="columns"> + <tr> + <td><TMPL_VAR NAME=name></td> + <td><TMPL_VAR NAME=type></td> + <td><TMPL_VAR NAME=size></td> + <td><TMPL_VAR NAME=key></td> + <TMPL_LOOP NAME=datamemory> + <td><TMPL_VAR NAME=val></td> + </TMPL_LOOP> + </tr> + </TMPL_LOOP> +</table> + +<p> </p> + +<h3>Indexes</h3> + +<p>We assume that indexes are ORDERED (not created USING HASH). If order is not required, 10 bytes of data memory can be saved per row if the index is created USING HASH</p> +<table> +<tr> + <th>Index</th> + <th>Type</th> + <th>Columns</th> + <TMPL_LOOP NAME=releases> + <th><TMPL_VAR NAME=rel> IdxMem</th> + </TMPL_LOOP> + <TMPL_LOOP NAME=releases> + <th><TMPL_VAR NAME=rel> DatMem</th> + </TMPL_LOOP> +</tr> +<TMPL_LOOP NAME="indexes"> + <tr> + <td><TMPL_VAR NAME=name></td> + <td><TMPL_VAR NAME=type></td> + <td><TMPL_VAR NAME=columns></td> + <TMPL_LOOP NAME=indexmemory> + <td><TMPL_VAR NAME=val></td> + </TMPL_LOOP> + <TMPL_LOOP NAME=datamemory> + <td><TMPL_VAR NAME=val></td> + </TMPL_LOOP> + </tr> +</TMPL_LOOP> +</table> + +<h3>DataMemory Usage</h3> +<table> +<tr> + <th> </th> + <TMPL_LOOP NAME=releases> + <th><TMPL_VAR NAME=rel></th> + </TMPL_LOOP> +</tr> +<tr> + <th>Row Overhead</th> + <TMPL_LOOP NAME=releases> + <td>16</td> + </TMPL_LOOP> +</tr> +<tr> + <th>Column DataMemory/Row</th> + <TMPL_LOOP NAME=RowDataMemory> + <td><TMPL_VAR NAME=val></td> + </TMPL_LOOP> +</tr> +<tr> + <th>Index DataMemory/Row</th> + <TMPL_LOOP NAME=IndexDataMemory> + <td><TMPL_VAR NAME=val></td> + </TMPL_LOOP> +</tr> +<tr> + <th>Total DataMemory/Row</th> + <TMPL_LOOP NAME=TotalDataMemory> + <td><TMPL_VAR NAME=val></td> + </TMPL_LOOP> +</tr> +<tr> + <th>Rows per 32kb page</th> + <TMPL_LOOP NAME=RowPerPage> + <td><TMPL_VAR NAME=val></td> + </TMPL_LOOP> +</tr> +<tr> + <th>Current number of rows</th> + <TMPL_LOOP NAME=count> + <td><TMPL_VAR NAME=val></td> + </TMPL_LOOP> +</tr> +<tr> + <th>Total DataMemory (kb)</th> + <TMPL_LOOP NAME=DataMemory> + <td><TMPL_VAR NAME=val></td> + </TMPL_LOOP> +</tr> +</table> + +<h3>IndexMemory Usage</h3> +<table> +<tr> + <th> </th> + <TMPL_LOOP NAME=releases> + <th><TMPL_VAR NAME=rel></th> + </TMPL_LOOP> +</tr> +<tr> + <th>IndexMemory/Row</th> + <TMPL_LOOP NAME=RowIndexMemory> + <td><TMPL_VAR NAME=val></td> + </TMPL_LOOP> +</tr> +<tr> + <th>Rows per 8kb page</th> + <TMPL_LOOP NAME=RowPerIndexPage> + <td><TMPL_VAR NAME=val></td> + </TMPL_LOOP> +</tr> +<tr> + <th>Current number of rows</th> + <TMPL_LOOP NAME=count> + <td><TMPL_VAR NAME=val></td> + </TMPL_LOOP> +</tr> +<tr> + <th>Total IndexMemory (kb)</th> + <TMPL_LOOP NAME=IndexMemory> + <td><TMPL_VAR NAME=val></td> + </TMPL_LOOP> +</tr> +</table> + +<hr/> +</TMPL_LOOP> + +<p>This is the output of ndb_size.pl.</p> +</body> +</html> + diff --git a/ndb/tools/restore/consumer_restore.cpp b/ndb/tools/restore/consumer_restore.cpp index 5786bdac697..552246a4f9e 100644 --- a/ndb/tools/restore/consumer_restore.cpp +++ b/ndb/tools/restore/consumer_restore.cpp @@ -38,7 +38,7 @@ BackupRestore::init() m_cluster_connection = new Ndb_cluster_connection(g_connect_string); if(m_cluster_connection->connect(12, 5, 1) != 0) { - return -1; + return false; } m_ndb = new Ndb(m_cluster_connection); diff --git a/os2/MySQL-Source.icc b/os2/MySQL-Source.icc index de0ac75ec9c..342cb6c96b9 100644 --- a/os2/MySQL-Source.icc +++ b/os2/MySQL-Source.icc @@ -12,7 +12,7 @@ group client_global_pch = 'm_ctype.h', 'mysqld_error.h', 'my_list.h', 'my_sys.h', 'my_net.h', 'myisam.h', 'myisampack.h', '.\myisam\myisamdef.h', - '.\regex\regex.h' + '.\regex\my_regex.h' group server_global_pch = 'os2.h', @@ -38,7 +38,7 @@ group server_global_pch = 'my_tree.h', '..\mysys\my_static.h', 'netdb.h', 'thr_alarm.h', 'heap.h', '..\myisam\fulltext.h', '..\myisam\ftdefs.h', 'myisammrg.h', - '.\regex\regex.h' + '.\regex\my_regex.h' group server_pch = 'ha_heap.h', 'ha_myisammrg.h', 'opt_ft.h', diff --git a/regex/Makefile.am b/regex/Makefile.am index 3b161287d36..7e8478e8123 100644 --- a/regex/Makefile.am +++ b/regex/Makefile.am @@ -18,7 +18,7 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include noinst_LIBRARIES = libregex.a LDADD= libregex.a $(top_builddir)/strings/libmystrings.a -noinst_HEADERS = cclass.h cname.h regex2.h utils.h engine.c regex.h +noinst_HEADERS = cclass.h cname.h regex2.h utils.h engine.c my_regex.h libregex_a_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c noinst_PROGRAMS = re re_SOURCES = split.c debug.c main.c diff --git a/regex/debug.c b/regex/debug.c index bdd3e00d5a7..271b09bb27a 100644 --- a/regex/debug.c +++ b/regex/debug.c @@ -2,7 +2,8 @@ #include <m_ctype.h> #include <m_string.h> #include <sys/types.h> -#include <regex.h> + +#include "my_regex.h" #include "utils.h" #include "regex2.h" #include "debug.ih" @@ -15,7 +16,7 @@ */ void regprint(r, d) -regex_t *r; +my_regex_t *r; FILE *d; { register struct re_guts *g = r->re_g; diff --git a/regex/debug.ih b/regex/debug.ih index 0d91e170437..1e1fb11177c 100644 --- a/regex/debug.ih +++ b/regex/debug.ih @@ -4,7 +4,7 @@ extern "C" { #endif /* === debug.c === */ -void regprint(regex_t *r, FILE *d); +void regprint(my_regex_t *r, FILE *d); static void s_print(CHARSET_INFO *charset, register struct re_guts *g, FILE *d); static char *regchar(CHARSET_INFO *charset, int ch,char *buf); diff --git a/regex/engine.c b/regex/engine.c index c4c4efe7e2f..1968ca61a96 100644 --- a/regex/engine.c +++ b/regex/engine.c @@ -32,7 +32,7 @@ struct match { struct re_guts *g; int eflags; - regmatch_t *pmatch; /* [nsub+1] (0 element unused) */ + my_regmatch_t *pmatch; /* [nsub+1] (0 element unused) */ char *offp; /* offsets work from here */ char *beginp; /* start of string -- virtual NUL precedes */ char *endp; /* end of string -- virtual NUL here */ @@ -68,7 +68,7 @@ CHARSET_INFO *charset; register struct re_guts *g; char *str; size_t nmatch; -regmatch_t pmatch[]; +my_regmatch_t pmatch[]; int eflags; { register char *endp; @@ -148,8 +148,8 @@ int eflags; /* oh my, he wants the subexpressions... */ if (m->pmatch == NULL) - m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) * - sizeof(regmatch_t)); + m->pmatch = (my_regmatch_t *)malloc((m->g->nsub + 1) * + sizeof(my_regmatch_t)); if (m->pmatch == NULL) { if (m->lastpos != NULL) free((char *)m->lastpos); diff --git a/regex/engine.ih b/regex/engine.ih index 7cfcb39fb2d..a9e98abef00 100644 --- a/regex/engine.ih +++ b/regex/engine.ih @@ -4,7 +4,7 @@ extern "C" { #endif /* === engine.c === */ -static int matcher(CHARSET_INFO *charset,register struct re_guts *g, char *string, size_t nmatch, regmatch_t pmatch[], int eflags); +static int matcher(CHARSET_INFO *charset,register struct re_guts *g, char *string, size_t nmatch, my_regmatch_t pmatch[], int eflags); static char *dissect(CHARSET_INFO *charset,register struct match *m, char *start, char *stop, sopno startst, sopno stopst); static char *backref(CHARSET_INFO *charset, register struct match *m, char *start, char *stop, sopno startst, sopno stopst, sopno lev); static char *fast(CHARSET_INFO *charset, register struct match *m, char *start, char *stop, sopno startst, sopno stopst); diff --git a/regex/main.c b/regex/main.c index 8fe16d74eee..fa97ca89047 100644 --- a/regex/main.c +++ b/regex/main.c @@ -1,9 +1,9 @@ #include <my_global.h> #include <m_string.h> #include <sys/types.h> -#include <regex.h> #include <assert.h> +#include "my_regex.h" #include "main.ih" char *progname; @@ -27,9 +27,9 @@ int main(argc, argv) int argc; char *argv[]; { - regex_t re; + my_regex_t re; # define NS 10 - regmatch_t subs[NS]; + my_regmatch_t subs[NS]; char erbuf[100]; int err; size_t len; @@ -74,9 +74,9 @@ char *argv[]; exit(status); } - err = regcomp(&re, argv[optind++], copts, &my_charset_latin1); + err = my_regcomp(&re, argv[optind++], copts, &my_charset_latin1); if (err) { - len = regerror(err, &re, erbuf, sizeof(erbuf)); + len = my_regerror(err, &re, erbuf, sizeof(erbuf)); fprintf(stderr, "error %s, %d/%d `%s'\n", eprint(err), (int) len, (int) sizeof(erbuf), erbuf); exit(status); @@ -84,7 +84,7 @@ char *argv[]; regprint(&re, stdout); if (optind >= argc) { - regfree(&re); + my_regfree(&re); exit(status); } @@ -92,9 +92,9 @@ char *argv[]; subs[0].rm_so = startoff; subs[0].rm_eo = strlen(argv[optind]) - endoff; } - err = regexec(&re, argv[optind], (size_t)NS, subs, eopts); + err = my_regexec(&re, argv[optind], (size_t)NS, subs, eopts); if (err) { - len = regerror(err, &re, erbuf, sizeof(erbuf)); + len = my_regerror(err, &re, erbuf, sizeof(erbuf)); fprintf(stderr, "error %s, %d/%d `%s'\n", eprint(err), (int) len, (int) sizeof(erbuf), erbuf); exit(status); @@ -136,7 +136,7 @@ FILE *in; const char *badpat = "invalid regular expression"; # define SHORT 10 const char *bpname = "REG_BADPAT"; - regex_t re; + my_regex_t re; while (fgets(inbuf, sizeof(inbuf), in) != NULL) { line++; @@ -163,27 +163,27 @@ FILE *in; options('c', f[1]) &~ REG_EXTENDED); } - ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf)); + ne = my_regerror(REG_BADPAT, (my_regex_t *)NULL, erbuf, sizeof(erbuf)); if (strcmp(erbuf, badpat) != 0 || ne != strlen(badpat)+1) { fprintf(stderr, "end: regerror() test gave `%s' not `%s'\n", erbuf, badpat); status = 1; } - ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, (size_t)SHORT); + ne = my_regerror(REG_BADPAT, (my_regex_t *)NULL, erbuf, (size_t)SHORT); if (strncmp(erbuf, badpat, SHORT-1) != 0 || erbuf[SHORT-1] != '\0' || ne != strlen(badpat)+1) { fprintf(stderr, "end: regerror() short test gave `%s' not `%.*s'\n", erbuf, SHORT-1, badpat); status = 1; } - ne = regerror(REG_ITOA|REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf)); + ne = my_regerror(REG_ITOA|REG_BADPAT, (my_regex_t *)NULL, erbuf, sizeof(erbuf)); if (strcmp(erbuf, bpname) != 0 || ne != strlen(bpname)+1) { fprintf(stderr, "end: regerror() ITOA test gave `%s' not `%s'\n", erbuf, bpname); status = 1; } re.re_endp = bpname; - ne = regerror(REG_ATOI, &re, erbuf, sizeof(erbuf)); + ne = my_regerror(REG_ATOI, &re, erbuf, sizeof(erbuf)); if (atoi(erbuf) != (int)REG_BADPAT) { fprintf(stderr, "end: regerror() ATOI test gave `%s' not `%ld'\n", erbuf, (long)REG_BADPAT); @@ -208,9 +208,9 @@ char *f3; char *f4; int opts; /* may not match f1 */ { - regex_t re; + my_regex_t re; # define NSUBS 10 - regmatch_t subs[NSUBS]; + my_regmatch_t subs[NSUBS]; # define NSHOULD 15 char *should[NSHOULD]; int nshould; @@ -226,10 +226,10 @@ int opts; /* may not match f1 */ strcpy(f0copy, f0); re.re_endp = (opts®_PEND) ? f0copy + strlen(f0copy) : NULL; fixstr(f0copy); - err = regcomp(&re, f0copy, opts, &my_charset_latin1); + err = my_regcomp(&re, f0copy, opts, &my_charset_latin1); if (err != 0 && (!opt('C', f1) || err != efind(f2))) { /* unexpected error or wrong error */ - len = regerror(err, &re, erbuf, sizeof(erbuf)); + len = my_regerror(err, &re, erbuf, sizeof(erbuf)); fprintf(stderr, "%d: %s error %s, %d/%d `%s'\n", line, type, eprint(err), len, (int) sizeof(erbuf), erbuf); @@ -243,7 +243,7 @@ int opts; /* may not match f1 */ } if (err != 0) { - regfree(&re); + my_regfree(&re); return; } @@ -256,11 +256,11 @@ int opts; /* may not match f1 */ subs[0].rm_so = strchr(f2, '(') - f2 + 1; subs[0].rm_eo = strchr(f2, ')') - f2; } - err = regexec(&re, f2copy, NSUBS, subs, options('e', f1)); + err = my_regexec(&re, f2copy, NSUBS, subs, options('e', f1)); if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) { /* unexpected error or wrong error */ - len = regerror(err, &re, erbuf, sizeof(erbuf)); + len = my_regerror(err, &re, erbuf, sizeof(erbuf)); fprintf(stderr, "%d: %s exec error %s, %d/%d `%s'\n", line, type, eprint(err), len, (int) sizeof(erbuf), erbuf); @@ -282,7 +282,7 @@ int opts; /* may not match f1 */ } if (err != 0 || f4 == NULL) { - regfree(&re); + my_regfree(&re); return; } @@ -303,7 +303,7 @@ int opts; /* may not match f1 */ } } - regfree(&re); + my_regfree(&re); } /* @@ -404,7 +404,7 @@ register char *p; char * /* NULL or complaint */ check(str, sub, should) char *str; -regmatch_t sub; +my_regmatch_t sub; char *should; { register int len; @@ -485,7 +485,7 @@ int err; static char epbuf[100]; size_t len; - len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf)); + len = my_regerror(REG_ITOA|err, (my_regex_t *)NULL, epbuf, sizeof(epbuf)); assert(len <= sizeof(epbuf)); return(epbuf); } @@ -499,11 +499,11 @@ efind(name) char *name; { static char efbuf[100]; - regex_t re; + my_regex_t re; sprintf(efbuf, "REG_%s", name); assert(strlen(efbuf) < sizeof(efbuf)); re.re_endp = efbuf; - (void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf)); + (void) my_regerror(REG_ATOI, &re, efbuf, sizeof(efbuf)); return(atoi(efbuf)); } diff --git a/regex/main.ih b/regex/main.ih index 4b16e676ad3..f0104cc18c0 100644 --- a/regex/main.ih +++ b/regex/main.ih @@ -9,7 +9,7 @@ void rx_try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts); int options(int type, char *s); int opt(int c, char *s); void fixstr(register char *p); -char *check(char *str, regmatch_t sub, char *should); +char *check(char *str, my_regmatch_t sub, char *should); static char *eprint(int err); static int efind(char *name); diff --git a/regex/regex.h b/regex/my_regex.h index e0fb0c77dc9..0d1cedf5430 100644 --- a/regex/regex.h +++ b/regex/my_regex.h @@ -20,15 +20,15 @@ typedef struct { const char *re_endp; /* end pointer for REG_PEND */ struct re_guts *re_g; /* none of your business :-) */ CHARSET_INFO *charset; /* For ctype things */ -} regex_t; +} my_regex_t; typedef struct { regoff_t rm_so; /* start of match */ regoff_t rm_eo; /* end of match */ -} regmatch_t; +} my_regmatch_t; /* === regcomp.c === */ -extern int regcomp(regex_t *, const char *, int, CHARSET_INFO *charset); +extern int my_regcomp(my_regex_t *, const char *, int, CHARSET_INFO *charset); #define REG_BASIC 0000 #define REG_EXTENDED 0001 #define REG_ICASE 0002 @@ -58,11 +58,11 @@ extern int regcomp(regex_t *, const char *, int, CHARSET_INFO *charset); #define REG_INVARG 16 #define REG_ATOI 255 /* convert name to number (!) */ #define REG_ITOA 0400 /* convert number to name (!) */ -extern size_t regerror(int, const regex_t *, char *, size_t); +extern size_t my_regerror(int, const my_regex_t *, char *, size_t); /* === regexec.c === */ -extern int regexec(const regex_t *, const char *, size_t, regmatch_t [], int); +extern int my_regexec(const my_regex_t *, const char *, size_t, my_regmatch_t [], int); #define REG_NOTBOL 00001 #define REG_NOTEOL 00002 #define REG_STARTEND 00004 @@ -72,12 +72,12 @@ extern int regexec(const regex_t *, const char *, size_t, regmatch_t [], int); /* === regfree.c === */ -extern void regfree(regex_t *); +extern void my_regfree(my_regex_t *); /* === reginit.c === */ -extern void regex_init(CHARSET_INFO *cs); /* Should be called for multithread progs */ -extern void regex_end(void); /* If one wants a clean end */ +extern void my_regex_init(CHARSET_INFO *cs); /* Should be called for multithread progs */ +extern void my_regex_end(void); /* If one wants a clean end */ #ifdef __cplusplus } diff --git a/regex/regcomp.c b/regex/regcomp.c index 998b39379aa..9cba56a97dd 100644 --- a/regex/regcomp.c +++ b/regex/regcomp.c @@ -1,11 +1,11 @@ #include <my_global.h> #include <m_string.h> #include <m_ctype.h> -#include <regex.h> #ifdef __WIN__ #include <limits.h> #endif +#include "my_regex.h" #include "utils.h" #include "regex2.h" @@ -100,8 +100,8 @@ static int never = 0; /* for use in asserts; shuts lint up */ = #define REG_DUMP 0200 */ int /* 0 success, otherwise REG_something */ -regcomp(preg, pattern, cflags, charset) -regex_t *preg; +my_regcomp(preg, pattern, cflags, charset) +my_regex_t *preg; const char *pattern; int cflags; CHARSET_INFO *charset; @@ -117,7 +117,7 @@ CHARSET_INFO *charset; # define GOODFLAGS(f) ((f)&~REG_DUMP) #endif - regex_init(charset); /* Init cclass if neaded */ + my_regex_init(charset); /* Init cclass if neaded */ preg->charset=charset; cflags = GOODFLAGS(cflags); if ((cflags®_EXTENDED) && (cflags®_NOSPEC)) @@ -199,7 +199,7 @@ CHARSET_INFO *charset; /* win or lose, we're done */ if (p->error != 0) /* lose */ - regfree(preg); + my_regfree(preg); return(p->error); } diff --git a/regex/regerror.c b/regex/regerror.c index 9caa5b95a4c..489f2e35abb 100644 --- a/regex/regerror.c +++ b/regex/regerror.c @@ -1,8 +1,8 @@ #include <my_global.h> #include <m_string.h> #include <m_ctype.h> -#include <regex.h> +#include "my_regex.h" #include "utils.h" #include "regerror.ih" @@ -56,7 +56,7 @@ static struct rerr { */ /* ARGSUSED */ size_t -regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) +my_regerror(int errcode, const my_regex_t *preg, char *errbuf, size_t errbuf_size) { register struct rerr *r; register size_t len; @@ -101,7 +101,7 @@ regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) */ static char * regatoi(preg, localbuf) -const regex_t *preg; +const my_regex_t *preg; char *localbuf; { register struct rerr *r; diff --git a/regex/regerror.ih b/regex/regerror.ih index 2cb668c24f0..a4d048022f8 100644 --- a/regex/regerror.ih +++ b/regex/regerror.ih @@ -4,7 +4,7 @@ extern "C" { #endif /* === regerror.c === */ -static char *regatoi(const regex_t *preg, char *localbuf); +static char *regatoi(const my_regex_t *preg, char *localbuf); #ifdef __cplusplus } diff --git a/regex/regexec.c b/regex/regexec.c index 723289bd0ad..b7ad83ba883 100644 --- a/regex/regexec.c +++ b/regex/regexec.c @@ -8,11 +8,10 @@ #include <my_global.h> #include <m_string.h> #include <m_ctype.h> -#include <regex.h> #ifdef __WIN__ #include <limits.h> #endif - +#include "my_regex.h" #include "utils.h" #include "regex2.h" @@ -110,11 +109,11 @@ static int nope = 0; /* for use in asserts; shuts lint up */ * have been prototyped. */ int /* 0 success, REG_NOMATCH failure */ -regexec(preg, str, nmatch, pmatch, eflags) -const regex_t *preg; +my_regexec(preg, str, nmatch, pmatch, eflags) +const my_regex_t *preg; const char *str; size_t nmatch; -regmatch_t pmatch[]; +my_regmatch_t pmatch[]; int eflags; { register struct re_guts *g = preg->re_g; diff --git a/regex/regfree.c b/regex/regfree.c index 6ab50735075..f764fcdf84e 100644 --- a/regex/regfree.c +++ b/regex/regfree.c @@ -2,7 +2,7 @@ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> -#include <regex.h> +#include "my_regex.h" #include "utils.h" #include "regex2.h" @@ -12,8 +12,8 @@ = extern void regfree(regex_t *); */ void -regfree(preg) -regex_t *preg; +my_regfree(preg) +my_regex_t *preg; { register struct re_guts *g; diff --git a/regex/reginit.c b/regex/reginit.c index 74ad3dc6de4..f0b53e64be3 100644 --- a/regex/reginit.c +++ b/regex/reginit.c @@ -7,7 +7,7 @@ static bool regex_inited=0; -void regex_init(CHARSET_INFO *cs) +void my_regex_init(CHARSET_INFO *cs) { char buff[CCLASS_LAST][256]; int count[CCLASS_LAST]; @@ -67,7 +67,7 @@ void regex_init(CHARSET_INFO *cs) return; } -void regex_end() +void my_regex_end() { if (regex_inited) { diff --git a/scripts/mysql_config.sh b/scripts/mysql_config.sh index 16e50c044ca..5b35c0190a5 100644 --- a/scripts/mysql_config.sh +++ b/scripts/mysql_config.sh @@ -101,13 +101,16 @@ libs_r="$ldflags -L$pkglibdir -lmysqlclient_r @ZLIB_DEPS@ @LIBS@ @openssl_libs@" libs_r=`echo "$libs_r" | sed -e 's; \+; ;g' | sed -e 's;^ *;;' | sed -e 's; *\$;;'` cflags="-I$pkgincludedir @CFLAGS@ " #note: end space! include="-I$pkgincludedir" -embedded_libs="$ldflags -L$pkglibdir -lmysqld @LIBS@ @WRAPLIBS@ @innodb_system_libs@ $client_libs" +embedded_libs="$ldflags -L$pkglibdir -lmysqld @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @innodb_system_libs@" embedded_libs=`echo "$embedded_libs" | sed -e 's; \+; ;g' | sed -e 's;^ *;;' | sed -e 's; *\$;;'` # Remove some options that a client doesn't have to care about +# FIXME until we have a --cxxflags, we need to remove -Xa +# and -xstrconst to make --cflags usable for Sun Forte C++ for remove in DDBUG_OFF DSAFEMALLOC USAFEMALLOC DSAFE_MUTEX \ DPEDANTIC_SAFEMALLOC DUNIV_MUST_NOT_INLINE DFORCE_INIT_OF_VARS \ - DEXTRA_DEBUG DHAVE_purify 'O[0-9]' 'W[-A-Za-z]*' + DEXTRA_DEBUG DHAVE_purify 'O[0-9]' 'W[-A-Za-z]*' \ + Xa xstrconst do # The first option we might strip will always have a space before it because # we set -I$pkgincludedir as the first option @@ -120,13 +123,13 @@ usage () { Usage: $0 [OPTIONS] Options: --cflags [$cflags] - --include [$include] + --include [$include] --libs [$libs] --libs_r [$libs_r] --socket [$socket] --port [$port] --version [$version] - --libmysqld-libs [$embedded_libs] + --libmysqld-libs [$embedded_libs] EOF exit 1 } @@ -136,13 +139,13 @@ if test $# -le 0; then usage; fi while test $# -gt 0; do case $1 in --cflags) echo "$cflags" ;; - --include) echo "$include" ;; + --include) echo "$include" ;; --libs) echo "$libs" ;; --libs_r) echo "$libs_r" ;; --socket) echo "$socket" ;; --port) echo "$port" ;; --version) echo "$version" ;; - --embedded-libs | --embedded | --libmysqld-libs) echo "$embedded_libs" ;; + --embedded-libs | --embedded | --libmysqld-libs) echo "$embedded_libs" ;; *) usage ;; esac diff --git a/scripts/mysql_create_system_tables.sh b/scripts/mysql_create_system_tables.sh index 383f8b80dc8..babf3a1c83f 100644 --- a/scripts/mysql_create_system_tables.sh +++ b/scripts/mysql_create_system_tables.sh @@ -123,7 +123,7 @@ then c_u="$c_u CREATE TABLE user (" c_u="$c_u Host char(60) binary DEFAULT '' NOT NULL," c_u="$c_u User char(16) binary DEFAULT '' NOT NULL," - c_u="$c_u Password char(41) binary DEFAULT '' NOT NULL," + c_u="$c_u Password binary(41) DEFAULT '' NOT NULL," c_u="$c_u Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," c_u="$c_u Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," c_u="$c_u Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," diff --git a/scripts/mysql_fix_privilege_tables.sql b/scripts/mysql_fix_privilege_tables.sql index 45f3b8533b5..7dba854e313 100644 --- a/scripts/mysql_fix_privilege_tables.sql +++ b/scripts/mysql_fix_privilege_tables.sql @@ -156,9 +156,9 @@ alter table columns_priv comment='Column privileges'; ALTER TABLE user MODIFY Host char(60) NOT NULL default '', MODIFY User char(16) NOT NULL default '', - MODIFY Password char(41) NOT NULL default '', ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; ALTER TABLE user + MODIFY Password binary(41) NOT NULL default '', MODIFY Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, MODIFY Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, MODIFY Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh index 098cd894916..b2b85018d7a 100644 --- a/scripts/mysqld_multi.sh +++ b/scripts/mysqld_multi.sh @@ -4,7 +4,7 @@ use Getopt::Long; use POSIX qw(strftime); $|=1; -$VER="2.14"; +$VER="2.15"; $opt_config_file = undef(); $opt_example = 0; @@ -326,7 +326,6 @@ sub start_mysqlds() } else { - $options[$j]=~ s/;/\\;/g; $options[$j]= quote_opt_arg($options[$j]); $tmp.= " $options[$j]"; } diff --git a/server-tools/instance-manager/buffer.cc b/server-tools/instance-manager/buffer.cc index dd6e6e95704..8039ab24481 100644 --- a/server-tools/instance-manager/buffer.cc +++ b/server-tools/instance-manager/buffer.cc @@ -14,7 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION) #pragma implementation #endif diff --git a/server-tools/instance-manager/buffer.h b/server-tools/instance-manager/buffer.h index 0c4d1eda102..afc71320ecb 100644 --- a/server-tools/instance-manager/buffer.h +++ b/server-tools/instance-manager/buffer.h @@ -19,7 +19,7 @@ #include <my_global.h> #include <my_sys.h> -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE) #pragma interface #endif diff --git a/server-tools/instance-manager/command.cc b/server-tools/instance-manager/command.cc index 73dd49ef8b8..f76366d5661 100644 --- a/server-tools/instance-manager/command.cc +++ b/server-tools/instance-manager/command.cc @@ -14,7 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION) #pragma implementation #endif diff --git a/server-tools/instance-manager/command.h b/server-tools/instance-manager/command.h index 8ae4e33b92f..82ded800e65 100644 --- a/server-tools/instance-manager/command.h +++ b/server-tools/instance-manager/command.h @@ -16,7 +16,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE) #pragma interface #endif diff --git a/server-tools/instance-manager/guardian.cc b/server-tools/instance-manager/guardian.cc index 17f4204185a..a4c0cef41b3 100644 --- a/server-tools/instance-manager/guardian.cc +++ b/server-tools/instance-manager/guardian.cc @@ -15,7 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION) #pragma implementation #endif diff --git a/server-tools/instance-manager/guardian.h b/server-tools/instance-manager/guardian.h index 758c4a3f3bc..16180e72dc9 100644 --- a/server-tools/instance-manager/guardian.h +++ b/server-tools/instance-manager/guardian.h @@ -22,7 +22,7 @@ #include <my_sys.h> #include <my_list.h> -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE) #pragma interface #endif diff --git a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc index 5e1c3d2ea9f..0c3c1aee5b4 100644 --- a/server-tools/instance-manager/instance.cc +++ b/server-tools/instance-manager/instance.cc @@ -14,7 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION) #pragma implementation #endif diff --git a/server-tools/instance-manager/instance.h b/server-tools/instance-manager/instance.h index 003cbca8cef..adb66991685 100644 --- a/server-tools/instance-manager/instance.h +++ b/server-tools/instance-manager/instance.h @@ -19,7 +19,7 @@ #include <my_global.h> #include "instance_options.h" -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE) #pragma interface #endif diff --git a/server-tools/instance-manager/instance_map.cc b/server-tools/instance-manager/instance_map.cc index b3a207ae79f..611eda457f2 100644 --- a/server-tools/instance-manager/instance_map.cc +++ b/server-tools/instance-manager/instance_map.cc @@ -14,7 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION) #pragma implementation #endif diff --git a/server-tools/instance-manager/instance_map.h b/server-tools/instance-manager/instance_map.h index 47037e0d433..51971db4c2f 100644 --- a/server-tools/instance-manager/instance_map.h +++ b/server-tools/instance-manager/instance_map.h @@ -24,7 +24,7 @@ #include <my_sys.h> #include <hash.h> -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE) #pragma interface #endif diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc index 70950a91015..25609f489af 100644 --- a/server-tools/instance-manager/instance_options.cc +++ b/server-tools/instance-manager/instance_options.cc @@ -14,7 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION) #pragma implementation #endif @@ -469,7 +469,7 @@ int Instance_options::add_option(const char* option) case SAVE_WHOLE: *(selected_options->value)= tmp; return 0; - defaut: + default: break; } } diff --git a/server-tools/instance-manager/instance_options.h b/server-tools/instance-manager/instance_options.h index dc62d277a43..dae1c2695d1 100644 --- a/server-tools/instance-manager/instance_options.h +++ b/server-tools/instance-manager/instance_options.h @@ -21,7 +21,7 @@ #include "parse.h" #include "portability.h" -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE) #pragma interface #endif diff --git a/server-tools/instance-manager/listener.cc b/server-tools/instance-manager/listener.cc index 374946d3b73..a1c1a743c24 100644 --- a/server-tools/instance-manager/listener.cc +++ b/server-tools/instance-manager/listener.cc @@ -14,7 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION) #pragma implementation #endif diff --git a/server-tools/instance-manager/listener.h b/server-tools/instance-manager/listener.h index 67a090c3aa2..3f5a80f1f53 100644 --- a/server-tools/instance-manager/listener.h +++ b/server-tools/instance-manager/listener.h @@ -16,7 +16,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE) #pragma interface #endif diff --git a/server-tools/instance-manager/mysql_connection.cc b/server-tools/instance-manager/mysql_connection.cc index dfa12f6f6e2..4a32e95450e 100644 --- a/server-tools/instance-manager/mysql_connection.cc +++ b/server-tools/instance-manager/mysql_connection.cc @@ -14,7 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION) #pragma interface #endif diff --git a/server-tools/instance-manager/mysql_connection.h b/server-tools/instance-manager/mysql_connection.h index e0109ce234f..2ff55d81e57 100644 --- a/server-tools/instance-manager/mysql_connection.h +++ b/server-tools/instance-manager/mysql_connection.h @@ -16,7 +16,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE) #pragma interface #endif diff --git a/server-tools/instance-manager/options.cc b/server-tools/instance-manager/options.cc index 74ccade3a2c..b16fcabae01 100644 --- a/server-tools/instance-manager/options.cc +++ b/server-tools/instance-manager/options.cc @@ -14,7 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION) #pragma implementation #endif diff --git a/server-tools/instance-manager/options.h b/server-tools/instance-manager/options.h index a5cd049decf..3a60de2bb39 100644 --- a/server-tools/instance-manager/options.h +++ b/server-tools/instance-manager/options.h @@ -16,7 +16,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE) #pragma interface #endif diff --git a/server-tools/instance-manager/parse_output.cc b/server-tools/instance-manager/parse_output.cc index 4ec9a71bfd2..b5af3cb83a7 100644 --- a/server-tools/instance-manager/parse_output.cc +++ b/server-tools/instance-manager/parse_output.cc @@ -107,7 +107,6 @@ int parse_output_and_get_value(const char *command, const char *word, } } -pclose: /* we are not interested in the termination status */ pclose(output); diff --git a/server-tools/instance-manager/portability.h b/server-tools/instance-manager/portability.h index 9fc0fe58c0a..2bdeff71a72 100644 --- a/server-tools/instance-manager/portability.h +++ b/server-tools/instance-manager/portability.h @@ -1,7 +1,7 @@ #ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_PORTABILITY_H #define INCLUDES_MYSQL_INSTANCE_MANAGER_PORTABILITY_H -#if defined(__SCO_DS) && !defined(SHUT_RDWR) +#if defined(_SCO_DS) && !defined(SHUT_RDWR) #define SHUT_RDWR 2 #endif diff --git a/server-tools/instance-manager/protocol.cc b/server-tools/instance-manager/protocol.cc index cd1be805b6b..e14449746fd 100644 --- a/server-tools/instance-manager/protocol.cc +++ b/server-tools/instance-manager/protocol.cc @@ -74,7 +74,7 @@ int net_send_error(struct st_net *net, uint sql_errno) MYSQL_ERRMSG_SIZE]; // message char *pos= buff; - enum { ERROR_PACKET_CODE= 255 }; + const int ERROR_PACKET_CODE= 255; *pos++= ERROR_PACKET_CODE; int2store(pos, sql_errno); pos+= 2; @@ -95,7 +95,7 @@ int net_send_error_323(struct st_net *net, uint sql_errno) MYSQL_ERRMSG_SIZE]; // message char *pos= buff; - enum { ERROR_PACKET_CODE= 255 }; + const int ERROR_PACKET_CODE= 255; *pos++= ERROR_PACKET_CODE; int2store(pos, sql_errno); pos+= 2; @@ -148,14 +148,14 @@ int store_to_protocol_packet(Buffer *buf, const char *string, uint *position) int send_eof(struct st_net *net) { - char buff[1 + /* eof packet code */ - 2 + /* warning count */ - 2]; /* server status */ + uchar buff[1 + /* eof packet code */ + 2 + /* warning count */ + 2]; /* server status */ buff[0]=254; int2store(buff+1, 0); int2store(buff+3, 0); - return my_net_write(net, buff, sizeof buff); + return my_net_write(net, (char*) buff, sizeof buff); } int send_fields(struct st_net *net, LIST *fields) @@ -195,7 +195,7 @@ int send_fields(struct st_net *net, LIST *fields) int2store(send_buff.buffer + position, 1); /* charsetnr */ int4store(send_buff.buffer + position + 2, field->length); /* field length */ - send_buff.buffer[position+6]= FIELD_TYPE_STRING; /* type */ + send_buff.buffer[position+6]= (uint) FIELD_TYPE_STRING; /* type */ int2store(send_buff.buffer + position + 7, 0); /* flags */ send_buff.buffer[position + 9]= (char) 0; /* decimals */ send_buff.buffer[position + 10]= 0; diff --git a/server-tools/instance-manager/thread_registry.cc b/server-tools/instance-manager/thread_registry.cc index a7384c0fa13..fe665f410e5 100644 --- a/server-tools/instance-manager/thread_registry.cc +++ b/server-tools/instance-manager/thread_registry.cc @@ -14,7 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION) #pragma implementation #endif diff --git a/server-tools/instance-manager/thread_registry.h b/server-tools/instance-manager/thread_registry.h index 28899810f23..a1075e719d6 100644 --- a/server-tools/instance-manager/thread_registry.h +++ b/server-tools/instance-manager/thread_registry.h @@ -50,7 +50,7 @@ in manner, similar to ``quit'' signals. */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE) #pragma interface #endif diff --git a/server-tools/instance-manager/user_map.cc b/server-tools/instance-manager/user_map.cc index 93c4a2ade25..d901d1ca5ec 100644 --- a/server-tools/instance-manager/user_map.cc +++ b/server-tools/instance-manager/user_map.cc @@ -14,7 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION) #pragma interface #endif diff --git a/server-tools/instance-manager/user_map.h b/server-tools/instance-manager/user_map.h index 4c86edd93d9..a57174a37c3 100644 --- a/server-tools/instance-manager/user_map.h +++ b/server-tools/instance-manager/user_map.h @@ -16,7 +16,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __GNUC__ +#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE) #pragma interface #endif diff --git a/sql/Makefile.am b/sql/Makefile.am index 60c485d79f9..cd1de0ce3c9 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -62,7 +62,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \ parse_file.h sql_view.h sql_trigger.h \ sql_array.h sql_cursor.h \ - examples/ha_example.h examples/ha_archive.h \ + examples/ha_example.h ha_archive.h \ examples/ha_tina.h ha_blackhole.h \ ha_federated.h mysqld_SOURCES = sql_lex.cc sql_handler.cc \ @@ -98,7 +98,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ tztime.cc my_time.c my_decimal.cc\ sp_head.cc sp_pcontext.cc sp_rcontext.cc sp.cc \ sp_cache.cc parse_file.cc sql_trigger.cc \ - examples/ha_example.cc examples/ha_archive.cc \ + examples/ha_example.cc ha_archive.cc \ examples/ha_tina.cc ha_blackhole.cc \ ha_federated.cc diff --git a/sql/field.cc b/sql/field.cc index e8731cb0ea5..eeff2ec9881 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3438,7 +3438,7 @@ int Field_long::store(longlong nr, bool unsigned_val) else { if (nr < 0 && unsigned_val) - nr= INT_MAX32+1; // Generate overflow + nr= ((longlong) INT_MAX32) + 1; // Generate overflow if (nr < (longlong) INT_MIN32) { res=(int32) INT_MIN32; diff --git a/sql/examples/ha_archive.cc b/sql/ha_archive.cc index 7a0c957e5c3..7e5c89cfe39 100644 --- a/sql/examples/ha_archive.cc +++ b/sql/ha_archive.cc @@ -18,7 +18,7 @@ #pragma implementation // gcc: Class implementation #endif -#include "../mysql_priv.h" +#include "mysql_priv.h" #ifdef HAVE_ARCHIVE_DB #include "ha_archive.h" diff --git a/sql/examples/ha_archive.h b/sql/ha_archive.h index e2d8aa49add..e2d8aa49add 100644 --- a/sql/examples/ha_archive.h +++ b/sql/ha_archive.h diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 69c20bb7974..de458785534 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -1191,7 +1191,7 @@ Opens an InnoDB database. */ handlerton* innobase_init(void) /*===============*/ - /* out: TRUE if error */ + /* out: &innobase_hton, or NULL on error */ { static char current_dir[3]; /* Set if using current lib */ int err; @@ -2116,7 +2116,7 @@ innobase_rollback_to_savepoint( /* TODO: use provided savepoint data area to store savepoint data */ - longlong2str((ulonglong)savepoint, name, 36); + longlong2str((ulint)savepoint, name, 36); error = (int) trx_rollback_to_savepoint_for_mysql(trx, name, &mysql_binlog_cache_pos); @@ -2145,7 +2145,7 @@ innobase_release_savepoint( /* TODO: use provided savepoint data area to store savepoint data */ - longlong2str((ulonglong)savepoint, name, 36); + longlong2str((ulint)savepoint, name, 36); error = (int) trx_release_savepoint_for_mysql(trx, name); @@ -2186,7 +2186,7 @@ innobase_savepoint( /* TODO: use provided savepoint data area to store savepoint data */ char name[64]; - longlong2str((ulonglong)savepoint,name,36); + longlong2str((ulint)savepoint,name,36); error = (int) trx_savepoint_for_mysql(trx, name, (ib_longlong)0); @@ -2492,7 +2492,7 @@ Closes a handle to an InnoDB table. */ int ha_innobase::close(void) /*====================*/ - /* out: error number */ + /* out: 0 */ { DBUG_ENTER("ha_innobase::close"); @@ -6688,6 +6688,11 @@ ha_innobase::store_lock( prebuilt->select_lock_type = LOCK_NONE; prebuilt->stored_select_lock_type = LOCK_NONE; + } else if (thd->lex->sql_command == SQLCOM_CHECKSUM) { + /* Use consistent read for checksum table */ + + prebuilt->select_lock_type = LOCK_NONE; + prebuilt->stored_select_lock_type = LOCK_NONE; } else { prebuilt->select_lock_type = LOCK_S; prebuilt->stored_select_lock_type = LOCK_S; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 6b88656dd76..02769c1eb31 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1703,6 +1703,6 @@ int ha_myisam::ft_read(byte * buf) uint ha_myisam::checksum() const { - return (uint)file->s->state.checksum; + return (uint)file->state->checksum; } diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 709a7ed14e0..5018aa2990e 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1209,7 +1209,8 @@ inline ulong ha_ndbcluster::index_flags(uint idx_no, uint part, DBUG_ENTER("ha_ndbcluster::index_flags"); DBUG_PRINT("info", ("idx_no: %d", idx_no)); DBUG_ASSERT(get_index_type_from_table(idx_no) < index_flags_size); - DBUG_RETURN(index_type_flags[get_index_type_from_table(idx_no)]); + DBUG_RETURN(index_type_flags[get_index_type_from_table(idx_no)] | + HA_KEY_SCAN_NOT_ROR); } static void shrink_varchar(Field* field, const byte* & ptr, char* buf) diff --git a/sql/handler.cc b/sql/handler.cc index b7b599a0a90..39d9b706ed2 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -38,7 +38,7 @@ extern handlerton blackhole_hton; extern handlerton example_hton; #endif #ifdef HAVE_ARCHIVE_DB -#include "examples/ha_archive.h" +#include "ha_archive.h" extern handlerton archive_hton; #endif #ifdef HAVE_CSV_DB diff --git a/sql/handler.h b/sql/handler.h index f4f6a8592bb..50f697bc980 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -98,6 +98,13 @@ #define HA_ONLY_WHOLE_INDEX 16 /* Can't use part key searches */ #define HA_KEYREAD_ONLY 64 /* Support HA_EXTRA_KEYREAD */ +/* + Index scan will not return records in rowid order. Not guaranteed to be + set for unordered (e.g. HASH) indexes. +*/ +#define HA_KEY_SCAN_NOT_ROR 128 + + /* operations for disable/enable indexes */ #define HA_KEY_SWITCH_NONUNIQ 0 #define HA_KEY_SWITCH_ALL 1 diff --git a/sql/item.cc b/sql/item.cc index 92a7330374a..f826fc1d874 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -904,6 +904,7 @@ bool Item_splocal::fix_fields(THD *, Item **) DBUG_ASSERT(it->fixed); max_length= it->max_length; decimals= it->decimals; + unsigned_flag= it->unsigned_flag; fixed= 1; return FALSE; } @@ -1804,6 +1805,7 @@ Item_decimal::Item_decimal(const char *str_arg, uint length, name= (char*) str_arg; decimals= (uint8) decimal_value.frac; fixed= 1; + unsigned_flag= !decimal_value.sign(); max_length= my_decimal_precision_to_length(decimal_value.intg + decimals, decimals, unsigned_flag); } @@ -1813,6 +1815,7 @@ Item_decimal::Item_decimal(longlong val, bool unsig) int2my_decimal(E_DEC_FATAL_ERROR, val, unsig, &decimal_value); decimals= (uint8) decimal_value.frac; fixed= 1; + unsigned_flag= !decimal_value.sign(); max_length= my_decimal_precision_to_length(decimal_value.intg + decimals, decimals, unsigned_flag); } @@ -1823,6 +1826,7 @@ Item_decimal::Item_decimal(double val, int precision, int scale) double2my_decimal(E_DEC_FATAL_ERROR, val, &decimal_value); decimals= (uint8) decimal_value.frac; fixed= 1; + unsigned_flag= !decimal_value.sign(); max_length= my_decimal_precision_to_length(decimal_value.intg + decimals, decimals, unsigned_flag); } @@ -1835,6 +1839,7 @@ Item_decimal::Item_decimal(const char *str, const my_decimal *val_arg, name= (char*) str; decimals= (uint8) decimal_par; max_length= length; + unsigned_flag= !decimal_value.sign(); fixed= 1; } @@ -1844,8 +1849,9 @@ Item_decimal::Item_decimal(my_decimal *value_par) my_decimal2decimal(value_par, &decimal_value); decimals= (uint8) decimal_value.frac; fixed= 1; + unsigned_flag= !decimal_value.sign(); max_length= my_decimal_precision_to_length(decimal_value.intg + decimals, - decimals, !decimal_value.sign()); + decimals, unsigned_flag); } @@ -1855,8 +1861,9 @@ Item_decimal::Item_decimal(const char *bin, int precision, int scale) &decimal_value, precision, scale); decimals= (uint8) decimal_value.frac; fixed= 1; + unsigned_flag= !decimal_value.sign(); max_length= my_decimal_precision_to_length(precision, decimals, - !decimal_value.sign()); + unsigned_flag); } @@ -5227,6 +5234,36 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) (Item*) new Item_int(name, result, length)); break; } + case ROW_RESULT: + { + new_item= 0; + /* + If item and comp_item are both Item_rows and have same number of cols + then process items in Item_row one by one. If Item_row contain nulls + substitute it by Item_null. Otherwise just return. + */ + if (item->result_type() == comp_item->result_type() && + ((Item_row*)item)->cols() == ((Item_row*)comp_item)->cols()) + { + Item_row *item_row= (Item_row*)item,*comp_item_row= (Item_row*)comp_item; + if (item_row->null_inside()) + new_item= (Item*) new Item_null(name); + else + { + int i= item_row->cols() - 1; + for (; i >= 0; i--) + { + if (item_row->maybe_null && item_row->el(i)->is_null()) + { + new_item= (Item*) new Item_null(name); + break; + } + resolve_const_item(thd, item_row->addr(i), comp_item_row->el(i)); + } + } + } + break; + } case REAL_RESULT: { // It must REAL_RESULT double result= item->val_real(); @@ -5247,7 +5284,6 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) (Item*) new Item_decimal(name, result, length, decimals)); break; } - case ROW_RESULT: default: DBUG_ASSERT(0); } diff --git a/sql/item.h b/sql/item.h index 381ba98e193..4980ea41ee7 100644 --- a/sql/item.h +++ b/sql/item.h @@ -164,6 +164,7 @@ struct Hybrid_type_traits virtual my_decimal *val_decimal(Hybrid_type *val, my_decimal *buf) const; virtual String *val_str(Hybrid_type *val, String *buf, uint8 decimals) const; static const Hybrid_type_traits *instance(); + Hybrid_type_traits() {}; }; @@ -185,6 +186,7 @@ struct Hybrid_type_traits_decimal: public Hybrid_type_traits { return &val->dec_buf[val->used_dec_buf_no]; } virtual String *val_str(Hybrid_type *val, String *buf, uint8 decimals) const; static const Hybrid_type_traits_decimal *instance(); + Hybrid_type_traits_decimal() {}; }; @@ -215,6 +217,7 @@ struct Hybrid_type_traits_integer: public Hybrid_type_traits virtual String *val_str(Hybrid_type *val, String *buf, uint8 decimals) const { buf->set(val->integer, &my_charset_bin); return buf;} static const Hybrid_type_traits_integer *instance(); + Hybrid_type_traits_integer() {}; }; @@ -1502,6 +1505,7 @@ public: my_decimal *val_decimal(my_decimal *); int save_in_field(Field *field, bool no_conversions); enum Item_result result_type () const { return STRING_RESULT; } + enum Item_result cast_to_int_type() const { return INT_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; } // to prevent drop fixed flag (no need parent cleanup call) void cleanup() {} diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 48839abcb10..85ba8ff794d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -3072,14 +3072,14 @@ Item_func_regex::fix_fields(THD *thd, Item **ref) return FALSE; } int error; - if ((error= regcomp(&preg,res->c_ptr(), - ((cmp_collation.collation->state & - (MY_CS_BINSORT | MY_CS_CSSORT)) ? - REG_EXTENDED | REG_NOSUB : - REG_EXTENDED | REG_NOSUB | REG_ICASE), - cmp_collation.collation))) + if ((error= my_regcomp(&preg,res->c_ptr(), + ((cmp_collation.collation->state & + (MY_CS_BINSORT | MY_CS_CSSORT)) ? + REG_EXTENDED | REG_NOSUB : + REG_EXTENDED | REG_NOSUB | REG_ICASE), + cmp_collation.collation))) { - (void) regerror(error,&preg,buff,sizeof(buff)); + (void) my_regerror(error,&preg,buff,sizeof(buff)); my_error(ER_REGEXP_ERROR, MYF(0), buff); return TRUE; } @@ -3121,15 +3121,15 @@ longlong Item_func_regex::val_int() prev_regexp.copy(*res2); if (regex_compiled) { - regfree(&preg); + my_regfree(&preg); regex_compiled=0; } - if (regcomp(&preg,res2->c_ptr_safe(), - ((cmp_collation.collation->state & - (MY_CS_BINSORT | MY_CS_CSSORT)) ? - REG_EXTENDED | REG_NOSUB : - REG_EXTENDED | REG_NOSUB | REG_ICASE), - cmp_collation.collation)) + if (my_regcomp(&preg,res2->c_ptr_safe(), + ((cmp_collation.collation->state & + (MY_CS_BINSORT | MY_CS_CSSORT)) ? + REG_EXTENDED | REG_NOSUB : + REG_EXTENDED | REG_NOSUB | REG_ICASE), + cmp_collation.collation)) { null_value=1; return 0; @@ -3138,7 +3138,7 @@ longlong Item_func_regex::val_int() } } null_value=0; - return regexec(&preg,res->c_ptr(),0,(regmatch_t*) 0,0) ? 0 : 1; + return my_regexec(&preg,res->c_ptr(),0,(my_regmatch_t*) 0,0) ? 0 : 1; } @@ -3148,7 +3148,7 @@ void Item_func_regex::cleanup() Item_bool_func::cleanup(); if (regex_compiled) { - regfree(&preg); + my_regfree(&preg); regex_compiled=0; } DBUG_VOID_RETURN; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 09a0fa8c357..aa50593abf4 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1002,11 +1002,11 @@ public: #ifdef USE_REGEX -#include <regex.h> +#include "my_regex.h" class Item_func_regex :public Item_bool_func { - regex_t preg; + my_regex_t preg; bool regex_compiled; bool regex_is_const; String prev_regexp; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 3129ce5db45..b56d99cf245 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -545,6 +545,7 @@ struct Hybrid_type_traits_fast_decimal: public val->traits->div(val, u); } static const Hybrid_type_traits_fast_decimal *instance(); + Hybrid_type_traits_fast_decimal() {}; }; static const Hybrid_type_traits_fast_decimal fast_decimal_traits_instance; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index fc7bac89274..7e598543a38 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -284,7 +284,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; /* Flag set if setup_tables already done */ #define OPTION_SETUP_TABLES_DONE (1L << 30) // intern /* If not set then the thread will ignore all warnings with level notes. */ -#define OPTION_SQL_NOTES (1L << 31) // THD, user +#define OPTION_SQL_NOTES (1UL << 31) // THD, user /* Force the used temporary table to be a MyISAM table (because we will use fulltext functions when reading from it. diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 103fcf20c11..cb7939c3750 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1098,7 +1098,7 @@ void clean_up(bool print_message) my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR)); #endif /* HAVE_OPENSSL */ #ifdef USE_REGEX - regex_end(); + my_regex_end(); #endif if (print_message && errmesg) @@ -2605,7 +2605,7 @@ static int init_common_variables(const char *conf_file_name, int argc, set_var_init(); mysys_uses_curses=0; #ifdef USE_REGEX - regex_init(&my_charset_latin1); + my_regex_init(&my_charset_latin1); #endif if (!(default_charset_info= get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY, @@ -6219,7 +6219,7 @@ static void mysql_init_variables(void) #else have_openssl=SHOW_OPTION_NO; #endif -#ifdef HAVE_BROKEN_REALPATH +#if !defined(HAVE_REALPATH) || defined(HAVE_BROKEN_REALPATH) have_symlink=SHOW_OPTION_NO; #else have_symlink=SHOW_OPTION_YES; @@ -6916,7 +6916,7 @@ static void get_options(int argc,char **argv) usage(); exit(0); } -#if defined(HAVE_BROKEN_REALPATH) +#if !defined(HAVE_REALPATH) || defined(HAVE_BROKEN_REALPATH) my_use_symdir=0; my_disable_symlinks=1; have_symlink=SHOW_OPTION_NO; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index caefdf92633..d6b9ec282e0 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -5117,6 +5117,8 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree) if (cpk_scan) param->is_ror_scan= TRUE; } + if (param->table->file->index_flags(key, 0, TRUE) & HA_KEY_SCAN_NOT_ROR) + param->is_ror_scan= FALSE; DBUG_PRINT("exit", ("Records: %lu", (ulong) records)); DBUG_RETURN(records); } diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 2f54cce0275..37acce2934b 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -108,7 +108,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) WHERE t2.field IS NULL; */ if (tl->table->map & where_tables) - const_result= 0; + return 0; } else used_tables|= tl->table->map; @@ -119,7 +119,10 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) may be used as the real count. */ if (tl->table->file->table_flags() & HA_NOT_EXACT_COUNT) + { is_exact_count= FALSE; + count= 1; // ensure count != 0 + } else { tl->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); @@ -127,9 +130,6 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) } } - if (!const_result) - return 0; - /* Iterate through all items in the SELECT clause and replace COUNT(), MIN() and MAX() with constants (if possible). @@ -250,7 +250,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) } if (!count) { - /* If count != 1, then we know that is_exact_count == TRUE. */ + /* If count == 0, then we know that is_exact_count == TRUE. */ ((Item_sum_min*) item_sum)->clear(); /* Set to NULL. */ } else diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index f2a91d5b88b..d3964fe6e52 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5366,12 +5366,12 @@ ER_TOO_BIG_SCALE 42000 S1009 eng "Too big scale %d specified for column '%-.64s'. Maximum is %d." ER_TOO_BIG_PRECISION 42000 S1009 eng "Too big precision %d specified for column '%-.64s'. Maximum is %d." -ER_SCALE_BIGGER_THAN_PRECISION 42000 S1009 - eng "Scale may not be larger than the precision (column '%-.64s')." +ER_M_BIGGER_THAN_D 42000 S1009 + eng "For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '%-.64s')." ER_WRONG_LOCK_OF_SYSTEM_TABLE eng "You can't combine write-locking of system '%-.64s.%-.64s' table with other tables" ER_CONNECT_TO_FOREIGN_DATA_SOURCE - eng "Unable to connect to foreign data source - database '%s'!" + eng "Unable to connect to foreign data source - database '%.64s'!" ER_QUERY_ON_FOREIGN_DATA_SOURCE eng "There was a problem processing the query on the foreign data source. Data source error: '%-.64s'" ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST @@ -5400,7 +5400,7 @@ ER_DATETIME_FUNCTION_OVERFLOW 22008 ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG eng "Can't update table '%-.64s' in stored function/trigger because it is already used by statement which invoked this stored function/trigger." ER_VIEW_PREVENT_UPDATE - eng "The definition of table '%-.64s' prevents operation %s on table '%-.64s'." + eng "The definition of table '%-.64s' prevents operation %.64s on table '%-.64s'." ER_PS_NO_RECURSION eng "The prepared statement contains a stored routine call that refers to that same statement. It's not allowed to execute a prepared statement in such a recursive manner" ER_SP_CANT_SET_AUTOCOMMIT @@ -5419,5 +5419,3 @@ ER_ROW_IS_REFERENCED_2 23000 eng "Cannot delete or update a parent row: a foreign key constraint fails (%.192s)" ER_NO_REFERENCED_ROW_2 23000 eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)" -ER_M_BIGGER_THAN_D 42000 S1009 - eng "For float(M,D) or double(M,D), M must be >= D (column '%-.64s')." diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index bb182232e0d..771cb93ed9c 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -693,8 +693,8 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b) SYNOPSIS acl_getroot() thd thread handle. If all checks are OK, - thd->priv_user, thd->master_access are updated. - thd->host, thd->ip, thd->user are used for checks. + thd->security_ctx->priv_user/master_access are updated. + thd->security_ctx->host/ip/user are used for checks. mqh user resources; on success mqh is reset, else unchanged passwd scrambled & crypted password, received from client diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 715d38925aa..84574bf01b9 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2987,11 +2987,10 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, Check that the table and database that qualify the current field name are the same as the table reference we are going to search for the field. - We exclude from the test below NATURAL/USING joins and any nested join - that is an operand of NATURAL/USING join, because each column in such - joins may potentially originate from a different table. However, base - tables and views that are under some NATURAL/USING join are searched - as usual base tables/views. + Exclude from the test below nested joins because the columns in a + nested join generally originate from different tables. Nested joins + also have no table name, except when a nested join is a merge view + or an information schema table. We include explicitly table references with a 'field_translation' table, because if there are views over natural joins we don't want to search @@ -3001,8 +3000,8 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, TODO: Ensure that table_name, db_name and tables->db always points to something ! */ - if (/* Exclude natural joins and nested joins underlying natural joins. */ - (!(table_list->nested_join && table_list->join_columns) || + if (/* Exclude nested joins. */ + (!table_list->nested_join || /* Include merge views and information schema tables. */ table_list->field_translation) && /* @@ -3025,13 +3024,10 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, register_tree_change))) *actual_table= table_list; } - else if (!(table_list->nested_join && table_list->join_columns)) + else if (!table_list->nested_join) { - /* - 'table_list' is a stored table. It is so because the only type of nested - join passed to this procedure is a NATURAL/USING join or an operand of a - NATURAL/USING join. - */ + /* 'table_list' is a stored table. */ + DBUG_ASSERT(table_list->table); if ((fld= find_field_in_table(thd, table_list->table, name, length, check_grants_table, allow_rowid, cached_field_index_ptr))) @@ -4791,9 +4787,6 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, } DBUG_RETURN(test(thd->net.report_error)); -err: - if (arena) - thd->restore_active_arena(arena, &backup); err_no_arena: DBUG_RETURN(1); } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 7e99a5c65ee..4001a51f459 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -313,6 +313,7 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) SELECT_LEX *select_lex= &thd->lex->select_lex; DBUG_ENTER("mysql_prepare_delete"); + thd->allow_sum_func= 0; if (setup_tables(thd, &thd->lex->select_lex.context, &thd->lex->select_lex.top_join_list, table_list, conds, &select_lex->leaf_tables, diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 32178a0a07d..b7a2b6b0624 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -171,7 +171,6 @@ void lex_start(THD *thd, uchar *buf,uint length) lex->sql_command= lex->orig_sql_command= SQLCOM_END; lex->duplicates= DUP_ERROR; lex->ignore= 0; - thd->allow_sum_func= 0; lex->sphead= NULL; lex->spcont= NULL; lex->proc_list.first= 0; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 30398375360..ff2be0ae6fb 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -564,6 +564,8 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, { uint length; byte save_chr; + if (field == table->next_number_field) + table->auto_increment_field_not_null= TRUE; if ((length=(uint) (read_info.row_end-pos)) > field->field_length) length=field->field_length; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a5faff5cf61..e16d75165fd 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -246,7 +246,7 @@ end: SYNOPSIS check_user() - thd thread handle, thd->{host,user,ip} are used + thd thread handle, thd->security_ctx->{host,user,ip} are used command originator of the check: now check_user is called during connect and change user procedures; used for logging. @@ -261,8 +261,8 @@ end: are 'IN'. RETURN VALUE - 0 OK; thd->user, thd->master_access, thd->priv_user, thd->db and - thd->db_access are updated; OK is sent to client; + 0 OK; thd->security_ctx->user/master_access/priv_user/db_access and + thd->db are updated; OK is sent to client; -1 access denied or handshake error; error is sent to client; >0 error, not sent to client */ @@ -5644,8 +5644,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, and so on, the display width is ignored. */ char buf[32]; - my_snprintf(buf, sizeof(buf), - "TIMESTAMP(%s)", length, system_charset_info); + my_snprintf(buf, sizeof(buf), "TIMESTAMP(%s)", length); push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DEPRECATED_SYNTAX, ER(ER_WARN_DEPRECATED_SYNTAX), @@ -5751,7 +5750,7 @@ new_create_field(THD *thd, char *field_name, enum_field_types type, } if (new_field->length < new_field->decimals) { - my_error(ER_SCALE_BIGGER_THAN_PRECISION, MYF(0), field_name); + my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name); DBUG_RETURN(NULL); } new_field->length= diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5fc97385f15..1b1a35d2584 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2409,6 +2409,7 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond, !field->table->maybe_null || field->null_ptr) return; // Not a key. Skip it exists_optimize= KEY_OPTIMIZE_EXISTS; + DBUG_ASSERT(num_values == 1); } else { @@ -2460,7 +2461,26 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond, eq_func is NEVER true when num_values > 1 */ if (!eq_func) - return; + { + /* + Additional optimization: if we're processing + "t.key BETWEEN c1 AND c1" then proceed as if we were processing + "t.key = c1". + TODO: This is a very limited fix. A more generic fix is possible. + There are 2 options: + A) Make equality propagation code be able to handle BETWEEN + (including cases like t1.key BETWEEN t2.key AND t3.key) + B) Make range optimizer to infer additional "t.key = c" equalities + and use them in equality propagation process (see details in + OptimizerKBAndTodo) + */ + if ((cond->functype() == Item_func::BETWEEN) && + value[0]->eq(value[1], field->binary())) + eq_func= TRUE; + else + return; + } + if (field->result_type() == STRING_RESULT) { if ((*value)->result_type() != STRING_RESULT) @@ -2487,7 +2507,6 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond, } } } - DBUG_ASSERT(num_values == 1); /* For the moment eq_func is always true. This slot is reserved for future extensions where we want to remembers other things than just eq comparisons diff --git a/sql/sql_show.cc b/sql/sql_show.cc index cdd2818d897..b29cc1e7c48 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -794,7 +794,8 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet) field->sql_type(type); packet->append(type.ptr(), type.length(), system_charset_info); - if (field->has_charset() && !limited_mysql_mode && !foreign_db_mode) + if (field->has_charset() && + !(thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))) { if (field->charset() != share->table_charset) { @@ -833,7 +834,7 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet) has_default= (field->type() != FIELD_TYPE_BLOB && !(field->flags & NO_DEFAULT_VALUE_FLAG) && field->unireg_check != Field::NEXT_NUMBER && - !((foreign_db_mode || limited_mysql_mode) && + !((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) && has_now_default)); if (has_default) @@ -863,12 +864,13 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet) packet->append(tmp); } - if (!foreign_db_mode && !limited_mysql_mode && + if (!(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS) && table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD) packet->append(" on update CURRENT_TIMESTAMP",28); - if (field->unireg_check == Field::NEXT_NUMBER && !foreign_db_mode) + if (field->unireg_check == Field::NEXT_NUMBER && + !(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS)) packet->append(" auto_increment", 15 ); if (field->comment.length) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 635b512fe23..dba4168343a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4074,7 +4074,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) strxmov(table_name, table->db ,".", table->table_name, NullS); - t= table->table= open_ltable(thd, table, TL_READ_NO_INSERT); + t= table->table= open_ltable(thd, table, TL_READ); thd->clear_error(); // these errors shouldn't get client protocol->prepare_for_resend(); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index efdf1291305..f85ef355752 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -571,6 +571,7 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, bzero((char*) &tables,sizeof(tables)); // For ORDER BY tables.table= table; tables.alias= table_list->alias; + thd->allow_sum_func= 0; if (setup_tables(thd, &select_lex->context, &select_lex->top_join_list, table_list, conds, &select_lex->leaf_tables, diff --git a/sql/sql_view.cc b/sql/sql_view.cc index b45bca4ff67..36b49196456 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1394,12 +1394,13 @@ int view_checksum(THD *thd, TABLE_LIST *view) */ bool mysql_rename_view(THD *thd, - const char *new_name, - TABLE_LIST *view) + const char *new_name, + TABLE_LIST *view) { LEX_STRING pathstr, file; File_parser *parser; char view_path[FN_REFLEN]; + bool error= TRUE; DBUG_ENTER("mysql_rename_view"); @@ -1411,19 +1412,20 @@ mysql_rename_view(THD *thd, pathstr.length= strlen(view_path); if ((parser= sql_parse_prepare(&pathstr, thd->mem_root, 1)) && - is_equal(&view_type, parser->type())) { + is_equal(&view_type, parser->type())) + { char dir_buff[FN_REFLEN], file_buff[FN_REFLEN]; /* get view definition and source */ if (mysql_make_view(parser, view) || parser->parse((gptr)view, thd->mem_root, view_parameters + source_number_position, 1)) - DBUG_RETURN(1); + goto err; /* rename view and it's backups */ if (rename_in_schema_file(view->db, view->table_name, new_name, view->revision - 1, num_view_backups)) - DBUG_RETURN(1); + goto err; strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", view->db, "/", NullS); (void) unpack_filename(dir_buff, dir_buff); @@ -1436,11 +1438,13 @@ mysql_rename_view(THD *thd, - file_buff); if (sql_create_definition_file(&pathstr, &file, view_file_type, - (gptr)view, view_parameters, num_view_backups)) { + (gptr)view, view_parameters, + num_view_backups)) + { /* restore renamed view in case of error */ rename_in_schema_file(view->db, new_name, view->table_name, view->revision - 1, num_view_backups); - DBUG_RETURN(1); + goto err; } } else DBUG_RETURN(1); @@ -1448,5 +1452,13 @@ mysql_rename_view(THD *thd, /* remove cache entries */ query_cache_invalidate3(thd, view, 0); sp_cache_invalidate(); - DBUG_RETURN(0); + error= FALSE; + +err: + /* + We have to explicitly call destructor for view's LEX since it won't + be called otherwise. + */ + delete view->view; + DBUG_RETURN(error); } diff --git a/sql/table.cc b/sql/table.cc index 982d5e7ddc9..1b3a6173752 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2291,8 +2291,10 @@ TABLE_LIST *st_table_list::first_leaf_for_name_resolution() List_iterator_fast<TABLE_LIST> it(cur_nested_join->join_list); cur_table_ref= it++; /* - If 'this' is a RIGHT JOIN, the operands in 'join_list' are in reverse - order, thus the first operand is already at the front of the list. + If the current nested join is a RIGHT JOIN, the operands in + 'join_list' are in reverse order, thus the first operand is + already at the front of the list. Otherwise the first operand + is in the end of the list of join operands. */ if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT)) { @@ -2343,9 +2345,11 @@ TABLE_LIST *st_table_list::last_leaf_for_name_resolution() cur_nested_join; cur_nested_join= cur_table_ref->nested_join) { + cur_table_ref= cur_nested_join->join_list.head(); /* - If 'this' is a RIGHT JOIN, the operands in 'join_list' are in reverse - order, thus the last operand is in the end of the list. + If the current nested is a RIGHT JOIN, the operands in + 'join_list' are in reverse order, thus the last operand is in the + end of the list. */ if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT)) { @@ -2355,8 +2359,6 @@ TABLE_LIST *st_table_list::last_leaf_for_name_resolution() while ((next= it++)) cur_table_ref= next; } - else - cur_table_ref= cur_nested_join->join_list.head(); if (cur_table_ref->is_leaf_for_name_resolution()) break; } diff --git a/strings/decimal.c b/strings/decimal.c index 7816f340eef..ce00b9770b3 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -1033,7 +1033,7 @@ int decimal2ulonglong(decimal_t *from, ulonglong *to) { ulonglong y=x; x=x*DIG_BASE + *buf++; - if (unlikely(y > (ULONGLONG_MAX/DIG_BASE) || x < y)) + if (unlikely(y > ((ulonglong) ULONGLONG_MAX/DIG_BASE) || x < y)) { *to=y; return E_DEC_OVERFLOW; diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 637a0402b8e..454c506f0fe 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -504,7 +504,7 @@ fi # Clean up the BuildRoot %clean -[ "$RBR" != "/" ] && [ -d $RBR ] && rm -rf $RBR; +[ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT; %files server %defattr(-,root,root,0755) @@ -668,6 +668,11 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Thu Sep 29 2005 Lenz Grimmer <lenz@mysql.com> + +- fixed the removing of the RPM_BUILD_ROOT in the %clean section (the + $RBR variable did not get expanded, thus leaving old build roots behind) + * Thu Aug 04 2005 Lenz Grimmer <lenz@mysql.com> - Fixed the creation of the mysql user group account in the postinstall |