diff options
55 files changed, 1218 insertions, 525 deletions
diff --git a/BitKeeper/etc/collapsed b/BitKeeper/etc/collapsed index 1d220fdb31d..311c3813abf 100644 --- a/BitKeeper/etc/collapsed +++ b/BitKeeper/etc/collapsed @@ -5,7 +5,13 @@ 45001f7c3b2hhCXDKfUvzkX9TNe6VA 45002051rHJfMEXAIMiAZV0clxvKSA 4513d8e4Af4dQWuk13sArwofRgFDQw +45143312u0Tz4r0wPXCbUKwdHa2jWA +45143b90ewOQuTW8-jrB3ZSAQvMRJw +45184588w9U72A6KX1hUFeAC4shSHA +45185df8mZbxfp85FbA0VxUXkmDewA 4519a6c5BVUxEHTf5iJnjZkixMBs8g 451ab499rgdjXyOnUDqHu-wBDoS-OQ +451b110a3ZV6MITl93ehXk2wxrbW7g 45214442pBGT9KuZEGixBH71jTzbOA 45214a07hVsIGwvwa-WrO-jpeaSwVw +452a92d0-31-8wSzSfZi165fcGcXPA diff --git a/Makefile.am b/Makefile.am index d74615b624d..e45ae5222c0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -89,8 +89,18 @@ bin-dist: all $(top_builddir)/scripts/make_binary_distribution @MAKE_BINARY_DISTRIBUTION_OPTIONS@ # Remove BK's "SCCS" subdirectories from source distribution +# Create initial database files for Windows installations. dist-hook: rm -rf `find $(distdir) -type d -name SCCS -print` + if echo "$(distdir)" | grep -q '^/' ; then \ + scripts/mysql_install_db --no-defaults --windows \ + --basedir=$(top_srcdir) \ + --datadir="$(distdir)/win/data"; \ + else \ + scripts/mysql_install_db --no-defaults --windows \ + --basedir=$(top_srcdir) \ + --datadir="$$(pwd)/$(distdir)/win/data"; \ + fi tags: support-files/build-tags diff --git a/client/mysql.cc b/client/mysql.cc index 1d7abbbc38a..f845038d6b6 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -388,6 +388,21 @@ int main(int argc,char *argv[]) else status.add_to_history=1; status.exit_status=1; + + { + /* + The file descriptor-layer may be out-of-sync with the file-number layer, + so we make sure that "stdout" is really open. If its file is closed then + explicitly close the FD layer. + */ + int stdout_fileno_copy; + stdout_fileno_copy= dup(fileno(stdout)); /* Okay if fileno fails. */ + if (stdout_fileno_copy == -1) + fclose(stdout); + else + close(stdout_fileno_copy); /* Clean up dup(). */ + } + load_defaults("my",load_default_groups,&argc,&argv); defaults_argv=argv; if (get_options(argc, (char **) argv)) diff --git a/client/mysqltest.c b/client/mysqltest.c index 3d457261980..efb5f1915f4 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -668,9 +668,11 @@ void close_files() DBUG_ENTER("close_files"); 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) + { + DBUG_PRINT("info", ("closing file: %s", cur_file->file_name)); my_fclose(cur_file->file, MYF(0)); + } my_free((gptr)cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR)); cur_file->file_name= 0; } @@ -727,11 +729,6 @@ void die(const char *fmt, ...) va_start(args, fmt); if (fmt) { -#ifdef DBUG_ON - char buff[256]; - vsnprintf(buff, sizeof(buff), fmt, args); - DBUG_PRINT("error", ("%s", buff)); -#endif fprintf(stderr, "mysqltest: "); if (cur_file && cur_file != file_stack) fprintf(stderr, "In included file \"%s\": ", @@ -855,8 +852,10 @@ void warning_msg(const char *fmt, ...) dynstr_append_mem(&ds_warning_messages, buff, len); } +#ifndef __WIN__ len= vsnprintf(buff, sizeof(buff), fmt, args); dynstr_append_mem(&ds_warning_messages, buff, len); +#endif dynstr_append(&ds_warning_messages, "\n"); va_end(args); @@ -891,7 +890,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) die(NullS); if (!eval_result && (uint) stat_info.st_size != ds->length) { - DBUG_PRINT("info",("Size differs: result size: %u file size: %u", + DBUG_PRINT("info",("Size differs: result size: %u file size: %llu", ds->length, stat_info.st_size)); DBUG_PRINT("info",("result: '%s'", ds->str)); DBUG_RETURN(RESULT_LENGTH_MISMATCH); @@ -953,8 +952,8 @@ err: void check_result(DYNAMIC_STRING* ds) { - DBUG_ASSERT(result_file_name); DBUG_ENTER("check_result"); + DBUG_ASSERT(result_file_name); switch (dyn_string_cmp(ds, result_file_name)) { @@ -1436,7 +1435,7 @@ void do_source(struct st_command *command) #ifdef __WIN__ -/* Variables used for temuprary sh files used for emulating Unix on Windows */ +/* Variables used for temporary sh files used for emulating Unix on Windows */ char tmp_sh_name[64], tmp_sh_cmd[70]; void init_tmp_sh_file() @@ -1811,7 +1810,7 @@ void my_ungetc(int c) void read_until_delimiter(DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_delimiter) { - int c; + char c; DBUG_ENTER("read_until_delimiter"); DBUG_PRINT("enter", ("delimiter: %s, length: %d", ds_delimiter->str, ds_delimiter->length)); @@ -2559,7 +2558,7 @@ void do_get_errcodes(struct st_command *command) *to_ptr= 0; to->type= ERR_SQLSTATE; - DBUG_PRINT("info", ("ERR_SQLSTATE: %d", to->code.sqlstate)); + DBUG_PRINT("info", ("ERR_SQLSTATE: %s", to->code.sqlstate)); } else if (*p == 's') { @@ -2710,12 +2709,15 @@ char *get_string(char **to_ptr, char **from_ptr, void set_reconnect(MYSQL* mysql, int val) { + my_bool reconnect= val; + DBUG_ENTER("set_reconnect"); + DBUG_PRINT("info", ("val: %d", val)); #if MYSQL_VERSION_ID < 50000 - mysql->reconnect= val; + mysql->reconnect= reconnect; #else - int reconnect= val; mysql_options(mysql, MYSQL_OPT_RECONNECT, (char *)&reconnect); #endif + DBUG_VOID_RETURN; } @@ -3344,7 +3346,7 @@ int read_line(char *buf, int size) LINT_INIT(last_quote); start_lineno= cur_file->lineno; - DBUG_PRINT("info", ("start_lineno: %d", start_lineno)); + DBUG_PRINT("info", ("Starting to read at lineno: %d", start_lineno)); for (; p < buf_end ;) { skip_char= 0; @@ -3368,7 +3370,7 @@ int read_line(char *buf, int size) die("Missing end of block"); *p= 0; - DBUG_PRINT("info", ("end of file")); + DBUG_PRINT("info", ("end of file at line %d", cur_file->lineno)); DBUG_RETURN(1); } cur_file--; @@ -3391,17 +3393,21 @@ int read_line(char *buf, int size) if (end_of_query(c)) { *p= 0; - DBUG_PRINT("exit", ("Found delimiter '%s'", delimiter)); + DBUG_PRINT("exit", ("Found delimiter '%s' at line %d", + delimiter, cur_file->lineno)); DBUG_RETURN(0); } else if ((c == '{' && - (!strncasecmp(buf, "while", min(5, p - buf)) || - !strncasecmp(buf, "if", min(2, p - buf))))) + (!my_strnncoll_simple(charset_info, "while", 5, + buf, min(5, p - buf), 0) || + !my_strnncoll_simple(charset_info, "if", 2, + buf, min(2, p - buf), 0)))) { /* Only if and while commands can be terminated by { */ *p++= c; *p= 0; - DBUG_PRINT("exit", ("Found '{' indicating begining of block")); + DBUG_PRINT("exit", ("Found '{' indicating start of block at line %d", + cur_file->lineno)); DBUG_RETURN(0); } else if (c == '\'' || c == '"' || c == '`') @@ -3416,7 +3422,8 @@ int read_line(char *buf, int size) { /* Comments are terminated by newline */ *p= 0; - DBUG_PRINT("exit", ("Found newline in comment")); + DBUG_PRINT("exit", ("Found newline in comment at line: %d", + cur_file->lineno)); DBUG_RETURN(0); } break; @@ -3431,13 +3438,19 @@ int read_line(char *buf, int size) { /* Skip all space at begining of line */ if (c == '\n') - start_lineno= cur_file->lineno; /* Query hasn't started yet */ + { + /* Query hasn't started yet */ + start_lineno= cur_file->lineno; + DBUG_PRINT("info", ("Query hasn't started yet, start_lineno: %d", + start_lineno)); + } skip_char= 1; } else if (end_of_query(c)) { *p= 0; - DBUG_PRINT("exit", ("Found delimiter '%s'", delimiter)); + DBUG_PRINT("exit", ("Found delimiter '%s' at line: %d", + delimiter, cur_file->lineno)); DBUG_RETURN(0); } else if (c == '}') @@ -3445,7 +3458,8 @@ int read_line(char *buf, int size) /* A "}" need to be by itself in the begining of a line to terminate */ *p++= c; *p= 0; - DBUG_PRINT("exit", ("Found '}' in begining of a line")); + DBUG_PRINT("exit", ("Found '}' in begining of a line at line: %d", + cur_file->lineno)); DBUG_RETURN(0); } else if (c == '\'' || c == '"' || c == '`') @@ -3607,7 +3621,7 @@ void scan_command_for_warnings(struct st_command *command) *end= save; } - *ptr++; + ptr++; } DBUG_VOID_RETURN; } @@ -4315,7 +4329,7 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, bind[i].is_null= &is_null[i]; bind[i].length= &length[i]; - DBUG_PRINT("bind", ("col[%d]: buffer_type: %d, buffer_length: %d", + DBUG_PRINT("bind", ("col[%d]: buffer_type: %d, buffer_length: %lu", i, bind[i].buffer_type, bind[i].buffer_length)); } @@ -7265,5 +7279,3 @@ void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val) char *end= longlong10_to_str(val, buff, 10); replace_dynstr_append_mem(ds, buff, end - buff); } - - diff --git a/include/my_dbug.h b/include/my_dbug.h index bf2e8d9969b..8a8d622e2a3 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -36,7 +36,8 @@ extern void _db_enter_(const char *_func_,const char *_file_,uint _line_, extern void _db_return_(uint _line_,const char **_sfunc_,const char **_sfile_, uint *_slevel_); extern void _db_pargs_(uint _line_,const char *keyword); -extern void _db_doprnt_ _VARARGS((const char *format,...)); +extern void _db_doprnt_ _VARARGS((const char *format,...)) + ATTRIBUTE_FORMAT(printf, 1, 2); extern void _db_dump_(uint _line_,const char *keyword,const char *memory, uint length); extern void _db_output_(uint flag); diff --git a/include/my_time.h b/include/my_time.h index e52ef69475d..adce58b08d7 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -49,6 +49,16 @@ typedef long my_time_t; #define TIME_NO_ZERO_DATE (TIME_NO_ZERO_IN_DATE*2) #define TIME_INVALID_DATES (TIME_NO_ZERO_DATE*2) +#define MYSQL_TIME_WARN_TRUNCATED 1 +#define MYSQL_TIME_WARN_OUT_OF_RANGE 2 + +/* Limits for the TIME data type */ +#define TIME_MAX_HOUR 838 +#define TIME_MAX_MINUTE 59 +#define TIME_MAX_SECOND 59 +#define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + \ + TIME_MAX_SECOND) + enum enum_mysql_timestamp_type str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, uint flags, int *was_cut); @@ -61,7 +71,9 @@ ulonglong TIME_to_ulonglong(const MYSQL_TIME *time); my_bool str_to_time(const char *str,uint length, MYSQL_TIME *l_time, - int *was_cut); + int *warning); + +int check_time_range(struct st_mysql_time *time, int *warning); long calc_daynr(uint year,uint month,uint day); uint calc_days_in_year(uint year); diff --git a/myisam/sort.c b/myisam/sort.c index 00fbfe768dc..74e0d973c9c 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -324,7 +324,7 @@ pthread_handler_t thr_find_all_keys(void *arg) if (info->sort_info->got_error) goto err; - if (info->keyinfo->flag && HA_VAR_LENGTH_KEY) + if (info->keyinfo->flag & HA_VAR_LENGTH_KEY) { info->write_keys=write_keys_varlen; info->read_to_buffer=read_to_buffer_varlen; @@ -516,7 +516,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) { if (got_error) continue; - if (sinfo->keyinfo->flag && HA_VAR_LENGTH_KEY) + if (sinfo->keyinfo->flag & HA_VAR_LENGTH_KEY) { sinfo->write_keys=write_keys_varlen; sinfo->read_to_buffer=read_to_buffer_varlen; diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index 435ea73e8a3..42062b7ba24 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -152,9 +152,7 @@ sub collect_test_cases ($) { closedir TESTDIR; } - # To speed things up, we sort first in if the test require a restart - # or not, second in alphanumeric order. - + # Reorder the test cases in an order that wil make them faster to run if ( $::opt_reorder ) { @@ -207,7 +205,6 @@ sub collect_test_cases ($) { # Append the criteria for sorting, in order of importance. # push(@criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "1" : "0")); - push(@criteria, "restart=" . ($tinfo->{'master_restart'} ? "1" : "0")); # Group test with equal options together. # Ending with "~" makes empty sort later than filled push(@criteria, join("!", sort @{$tinfo->{'master_opt'}}) . "~"); @@ -313,18 +310,18 @@ sub collect_one_test_case($$$$$$$) { { # This is an ndb test or all tests should be run with ndb cluster started $tinfo->{'ndb_test'}= 1; - if ( $::opt_skip_ndbcluster ) + if ( ! $::opt_ndbcluster_supported ) { - # All ndb test's should be skipped + # Ndb is not supported, skip them $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "No ndbcluster test(--skip-ndbcluster)"; + $tinfo->{'comment'}= "No ndbcluster support"; return; } - if ( ! $::opt_ndbcluster_supported ) + elsif ( $::opt_skip_ndbcluster ) { - # Ndb is not supported, skip them + # All ndb test's should be skipped $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "No ndbcluster support"; + $tinfo->{'comment'}= "No ndbcluster tests(--skip-ndbcluster)"; return; } } @@ -357,52 +354,58 @@ sub collect_one_test_case($$$$$$$) { if ( -f $master_opt_file ) { - $tinfo->{'master_restart'}= 1; # We think so for now - MASTER_OPT: - { - my $master_opt= mtr_get_opts_from_file($master_opt_file); + my $master_opt= mtr_get_opts_from_file($master_opt_file); - foreach my $opt ( @$master_opt ) - { - my $value; + foreach my $opt ( @$master_opt ) + { + my $value; - # This is a dirty hack from old mysql-test-run, we use the opt - # file to flag other things as well, it is not a opt list at - # all + # The opt file is used both to send special options to the mysqld + # as well as pass special test case specific options to this + # script - $value= mtr_match_prefix($opt, "--timezone="); - if ( defined $value ) - { - $tinfo->{'timezone'}= $value; - last MASTER_OPT; - } + $value= mtr_match_prefix($opt, "--timezone="); + if ( defined $value ) + { + $tinfo->{'timezone'}= $value; + next; + } - $value= mtr_match_prefix($opt, "--result-file="); - if ( defined $value ) - { - $tinfo->{'result_file'}= "r/$value.result"; - $tinfo->{'master_restart'}= 0; - last MASTER_OPT; - } + $value= mtr_match_prefix($opt, "--result-file="); + if ( defined $value ) + { + # Specifies the file mysqltest should compare + # output against + $tinfo->{'result_file'}= "r/$value.result"; + next; + } - # If we set default time zone, remove the one we have - $value= mtr_match_prefix($opt, "--default-time-zone="); - if ( defined $value ) - { - $tinfo->{'master_opt'}= []; - } + # If we set default time zone, remove the one we have + $value= mtr_match_prefix($opt, "--default-time-zone="); + if ( defined $value ) + { + $tinfo->{'timezone'}= ""; + # Fallthrough, add this option + } + # The --restart option forces a restart even if no special + # option is set. If the options are the same as next testcase + # there is no need to restart after the testcase + # has completed + if ( $opt eq "--force-restart" ) + { + $tinfo->{'force_restart'}= 1; + next; } - # Ok, this was a real option list, add it - push(@{$tinfo->{'master_opt'}}, @$master_opt); + # Ok, this was a real option, add it + push(@{$tinfo->{'master_opt'}}, $opt); } } if ( -f $slave_opt_file ) { - $tinfo->{'slave_restart'}= 1; my $slave_opt= mtr_get_opts_from_file($slave_opt_file); foreach my $opt ( @$slave_opt ) @@ -417,7 +420,6 @@ sub collect_one_test_case($$$$$$$) { if ( -f $slave_mi_file ) { $tinfo->{'slave_mi'}= mtr_get_opts_from_file($slave_mi_file); - $tinfo->{'slave_restart'}= 1; } if ( -f $master_sh ) @@ -431,7 +433,6 @@ sub collect_one_test_case($$$$$$$) { else { $tinfo->{'master_sh'}= $master_sh; - $tinfo->{'master_restart'}= 1; } } @@ -446,7 +447,6 @@ sub collect_one_test_case($$$$$$$) { else { $tinfo->{'slave_sh'}= $slave_sh; - $tinfo->{'slave_restart'}= 1; } } @@ -551,17 +551,6 @@ sub collect_one_test_case($$$$$$$) { return; } } - - # We can't restart a running server that may be in use - - if ( $::glob_use_running_server and - ( $tinfo->{'master_restart'} or $tinfo->{'slave_restart'} ) ) - { - $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "Can't restart a running server"; - return; - } - } @@ -586,8 +575,6 @@ sub mtr_options_from_test_file($$) { while ( my $line= <$F> ) { - next if ( $line !~ /^--/ ); - # Match this line against tag in "tags" array foreach my $tag (@tags) { @@ -599,14 +586,21 @@ sub mtr_options_from_test_file($$) { } # If test sources another file, open it as well - if ( $line =~ /^\-\-([[:space:]]*)source(.*)$/ ) + if ( $line =~ /^\-\-([[:space:]]*)source(.*)$/ or + $line =~ /^([[:space:]]*)source(.*);$/ ) { my $value= $2; $value =~ s/^\s+//; # Remove leading space $value =~ s/[[:space:]]+$//; # Remove ending space my $sourced_file= "$::glob_mysql_test_dir/$value"; - mtr_options_from_test_file($tinfo, $sourced_file); + if ( -f $sourced_file ) + { + # Only source the file if it exists, we may get + # false positives in the regexes above if someone + # writes "source nnnn;" in a test case(such as mysqltest.test) + mtr_options_from_test_file($tinfo, $sourced_file); + } } } diff --git a/mysql-test/lib/mtr_gcov.pl b/mysql-test/lib/mtr_gcov.pl index 07aac1d2017..71d3d6a2a43 100644 --- a/mysql-test/lib/mtr_gcov.pl +++ b/mysql-test/lib/mtr_gcov.pl @@ -23,12 +23,28 @@ sub gcov_prepare () { -or -name \*.da | xargs rm`; } +# Used by gcov +our @mysqld_src_dirs= + ( + "strings", + "mysys", + "include", + "extra", + "regex", + "isam", + "merge", + "myisam", + "myisammrg", + "heap", + "sql", + ); + sub gcov_collect () { print "Collecting source coverage info...\n"; -f $::opt_gcov_msg and unlink($::opt_gcov_msg); -f $::opt_gcov_err and unlink($::opt_gcov_err); - foreach my $d ( @::mysqld_src_dirs ) + foreach my $d ( @mysqld_src_dirs ) { chdir("$::glob_basedir/$d"); foreach my $f ( (glob("*.h"), glob("*.cc"), glob("*.c")) ) diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index 5e21248790e..2831c179ea5 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -339,19 +339,6 @@ sub mtr_kill_leftovers () { mtr_report("Killing Possible Leftover Processes"); mtr_debug("mtr_kill_leftovers(): started."); - mkpath("$::opt_vardir/log"); # Needed for mysqladmin log - - # Stop or kill Instance Manager and all its children. If we failed to do - # that, we can only abort -- there is nothing left to do. - -# mtr_error("Failed to stop Instance Manager.") -# unless mtr_im_stop($::instance_manager); - - # Start shutdown of masters and slaves. Don't touch IM-managed mysqld - # instances -- they should be stopped by mtr_im_stop(). - - mtr_debug("Shutting down mysqld-instances..."); - my @kill_pids; my %admin_pids; diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index 4708de92e07..b173896d48a 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -133,6 +133,7 @@ sub mtr_report_test_failed ($) { if ( $tinfo->{'timeout'} ) { print "[ fail ] timeout\n"; + return; } elsif ( $tinfo->{'ndb_test'} and $::cluster->[0]->{'installed_ok'} eq "NO") { @@ -172,7 +173,7 @@ sub mtr_report_stats ($) { my $tot_failed= 0; my $tot_tests= 0; my $tot_restarts= 0; - my $found_problems= 0; # Some warnings are errors... + my $found_problems= 0; # Some warnings in the logfiles are errors... foreach my $tinfo (@$tests) { @@ -283,6 +284,7 @@ sub mtr_report_stats ($) { print "\n"; + # Print a list of testcases that failed if ( $tot_failed != 0 ) { my $test_mode= join(" ", @::glob_test_mode) || "default"; @@ -296,7 +298,30 @@ sub mtr_report_stats ($) { } } print "\n"; + } + + # Print a list of check_testcases that failed(if any) + if ( $::opt_check_testcases ) + { + my @check_testcases= (); + + foreach my $tinfo (@$tests) + { + if ( defined $tinfo->{'check_testcase_failed'} ) + { + push(@check_testcases, $tinfo->{'name'}); + } + } + + if ( @check_testcases ) + { + print "Check of testcase failed for: "; + print join(" ", @check_testcases); + print "\n\n"; + } + } + if ( $tot_failed != 0 || $found_problems) { mtr_error("there where failing test cases"); diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 5ba42fb2c25..35782733b20 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -65,7 +65,7 @@ use IO::Socket; use IO::Socket::INET; use Data::Dumper; use strict; -#use diagnostics; +use diagnostics; our $glob_win32_perl= ($^O eq "MSWin32"); # ActiveState Win32 Perl our $glob_cygwin_perl= ($^O eq "cygwin"); # Cygwin Perl @@ -87,22 +87,6 @@ require "lib/mtr_stress.pl"; $Devel::Trace::TRACE= 1; -# Used by gcov -our @mysqld_src_dirs= - ( - "strings", - "mysys", - "include", - "extra", - "regex", - "isam", - "merge", - "myisam", - "myisammrg", - "heap", - "sql", - ); - ############################################################################## # # Default settings @@ -311,8 +295,8 @@ our $used_binlog_format; our $debug_compiled_binaries; our $glob_tot_real_time= 0; -# Default values read from mysqld -our $default_mysqld_port; +our %mysqld_variables; + ###################################################################### # @@ -326,7 +310,7 @@ sub command_line_setup (); sub datadir_setup (); sub executable_setup (); sub environment_setup (); -sub kill_running_server (); +sub kill_running_servers (); sub cleanup_stale_files (); sub check_ssl_support ($); sub check_running_as_root(); @@ -368,7 +352,13 @@ sub main () { initial_setup(); command_line_setup(); + + check_ndbcluster_support(\%mysqld_variables); + check_ssl_support(\%mysqld_variables); + check_debug_support(\%mysqld_variables); + executable_setup(); + environment_setup(); signal_setup(); @@ -478,11 +468,11 @@ sub initial_setup () { # # Look for the path where to find the client binaries - $path_client_bindir= mtr_path_exists("$glob_basedir/client", - "$glob_basedir/client_release", + $path_client_bindir= mtr_path_exists("$glob_basedir/client_release", "$glob_basedir/client_debug", "$glob_basedir/client/release", "$glob_basedir/client/debug", + "$glob_basedir/client", "$glob_basedir/bin"); # Look for the mysqld executable @@ -494,14 +484,12 @@ sub initial_setup () { "$path_client_bindir/mysqld-debug", "$path_client_bindir/mysqld-max", "$glob_basedir/libexec/mysqld", + "$glob_basedir/bin/mysqld", "$glob_basedir/sql/release/mysqld", "$glob_basedir/sql/debug/mysqld"); - $exe_master_mysqld= $exe_master_mysqld || $exe_mysqld; - $exe_slave_mysqld= $exe_slave_mysqld || $exe_mysqld; - # Use the mysqld found above to find out what features are available - check_mysqld_features(); + collect_mysqld_features(); } @@ -721,7 +709,6 @@ sub command_line_setup () { # -------------------------------------------------------------------------- # Find out type of logging that are being used # -------------------------------------------------------------------------- - # NOTE if the default binlog format is changed, this has to be changed $used_binlog_format= "stmt"; foreach my $arg ( @opt_extra_mysqld_opt ) @@ -762,7 +749,6 @@ sub command_line_setup () { # -------------------------------------------------------------------------- # Set the "var/" directory, as it is the base for everything else # -------------------------------------------------------------------------- - $default_vardir= "$glob_mysql_test_dir/var"; if ( ! $opt_vardir ) { @@ -792,25 +778,46 @@ sub command_line_setup () { } # -------------------------------------------------------------------------- - # If not set, set these to defaults + # Set tmpdir # -------------------------------------------------------------------------- - $opt_tmpdir= "$opt_vardir/tmp" unless $opt_tmpdir; $opt_tmpdir =~ s,/+$,,; # Remove ending slash if any # -------------------------------------------------------------------------- - # Do sanity checks of command line arguments + # Set socket # -------------------------------------------------------------------------- + if (!$opt_socket) + { + $opt_socket= $mysqld_variables{'socket'}; + } # -------------------------------------------------------------------------- - # Look at the command line options and set script flags + # Check im suport # -------------------------------------------------------------------------- + if ( $mysql_version_id < 50000 ) + { + # Instance manager is not supported until 5.0 + $opt_skip_im= 1; + } + + if ( $glob_win32 ) + { + mtr_report("Disable Instance manager - not supported on Windows"); + $opt_skip_im= 1; + } + + # -------------------------------------------------------------------------- + # Record flag + # -------------------------------------------------------------------------- if ( $opt_record and ! @opt_cases ) { mtr_error("Will not run in record mode without a specific test case"); } + # -------------------------------------------------------------------------- + # Embedded server flag + # -------------------------------------------------------------------------- if ( $opt_embedded_server ) { $glob_use_embedded_server= 1; @@ -825,11 +832,18 @@ sub command_line_setup () { } } + + # -------------------------------------------------------------------------- + # ps protcol flag + # -------------------------------------------------------------------------- if ( $opt_ps_protocol ) { push(@glob_test_mode, "ps-protocol"); } + # -------------------------------------------------------------------------- + # Ndb cluster flags + # -------------------------------------------------------------------------- if ( $opt_with_ndbcluster and $opt_skip_ndbcluster) { mtr_error("Can't specify both --with-ndbcluster and --skip-ndbcluster"); @@ -865,22 +879,33 @@ sub command_line_setup () { $opt_ndbconnectstring_slave= "host=localhost:$opt_ndbcluster_port_slave"; } + # -------------------------------------------------------------------------- + # Bench flags + # -------------------------------------------------------------------------- if ( $opt_small_bench ) { $opt_bench= 1; } + # -------------------------------------------------------------------------- + # Sleep flag + # -------------------------------------------------------------------------- if ( $opt_sleep ) { $opt_sleep_time_after_restart= $opt_sleep; } + # -------------------------------------------------------------------------- + # Gcov flag + # -------------------------------------------------------------------------- if ( $opt_gcov and ! $opt_source_dist ) { mtr_error("Coverage test needs the source - please use source dist"); } + # -------------------------------------------------------------------------- # Check debug related options + # -------------------------------------------------------------------------- if ( $opt_gdb || $opt_client_gdb || $opt_ddd || $opt_client_ddd || $opt_manual_gdb || $opt_manual_ddd || $opt_manual_debug || $opt_debugger || $opt_client_debugger ) @@ -895,13 +920,15 @@ sub command_line_setup () { } } - # Check IM arguments - if ( $glob_win32 ) - { - mtr_report("Disable Instance manager - not supported on Windows"); - $opt_skip_im= 1; - } + # -------------------------------------------------------------------------- + # Check if special exe was selected for master or slave + # -------------------------------------------------------------------------- + $exe_master_mysqld= $exe_master_mysqld || $exe_mysqld; + $exe_slave_mysqld= $exe_slave_mysqld || $exe_mysqld; + + # -------------------------------------------------------------------------- # Check valgrind arguments + # -------------------------------------------------------------------------- if ( $opt_valgrind or $opt_valgrind_path or defined $opt_valgrind_options) { mtr_report("Turning on valgrind for all executables"); @@ -1185,7 +1212,7 @@ sub datadir_setup () { ############################################################################## -sub check_mysqld_features () { +sub collect_mysqld_features () { # # Execute "mysqld --no-defaults --help --verbose", that will # print out version and a list of all features and settings @@ -1202,7 +1229,6 @@ sub check_mysqld_features () { $exe_mysqld); } - my %mysqld_variables; my $F= IO::File->new($spec_file) or mtr_error("can't open file \"$spec_file\": $!"); @@ -1263,27 +1289,6 @@ sub check_mysqld_features () { mtr_error("Could not find version of MySQL") unless $mysql_version_id; mtr_error("Could not find variabes list") unless $found_variable_list_start; - check_ndbcluster_support(\%mysqld_variables); - check_ssl_support(\%mysqld_variables); - check_debug_support(\%mysqld_variables); - - if ( $mysql_version_id < 50000 ) - { - # Instance manager is not supported until 5.0 - $opt_skip_im= 1; - - } - - if ( $mysql_version_id < 50100 ) - { - # Slave cluster is not supported until 5.1 - $opt_skip_ndbcluster_slave= 1; - - } - - # Set default values from mysqld_variables - $opt_socket= $mysqld_variables{'socket'}; - $default_mysqld_port = $mysqld_variables{'port'}; } @@ -1353,10 +1358,13 @@ sub executable_setup () { $exe_mysqlslap= mtr_exe_exists("$path_client_bindir/mysqlslap"); } - # Look for mysql_fix_system_table script - $exe_mysql_fix_system_tables= - mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables", - "$path_client_bindir/mysql_fix_privilege_tables"); + if ( ! $glob_win32 ) + { + # Look for mysql_fix_system_table script + $exe_mysql_fix_system_tables= + mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables", + "$path_client_bindir/mysql_fix_privilege_tables"); + } if ( ! $opt_skip_ndbcluster) { @@ -1379,11 +1387,14 @@ sub executable_setup () { mtr_exe_exists("$ndb_path/src/kernel/ndbd", "$glob_basedir/bin/ndbd"); - $path_ndb_examples_dir= - mtr_path_exists("$ndb_path/ndbapi-examples", - "$ndb_path/examples"); - $exe_ndb_example= - mtr_file_exists("$path_ndb_examples_dir/ndbapi_simple/ndbapi_simple"); + if ( $mysql_version_id >= 50000 ) + { + $path_ndb_examples_dir= + mtr_path_exists("$ndb_path/ndbapi-examples", + "$ndb_path/examples"); + $exe_ndb_example= + mtr_file_exists("$path_ndb_examples_dir/ndbapi_simple/ndbapi_simple"); + } } # Look for the udf_example library @@ -1406,17 +1417,27 @@ sub executable_setup () { } - # Look for mysql_client_test executable - if ( $glob_use_embedded_server ) + if ( $glob_win32 and $mysql_version_id < 50000 ) { - $exe_mysql_client_test= - mtr_exe_exists("$glob_basedir/libmysqld/examples/mysql_client_test_embedded", - "$glob_basedir/tests/mysqltest_embedded"); + # Skip looking for exe_mysql_client_test as its not built by default + # in 4.1 for windows. + $exe_mysql_client_test= "unavailable"; } else { - $exe_mysql_client_test= - mtr_exe_exists("$glob_basedir/tests/mysql_client_test"); + # Look for mysql_client_test executable + if ( $glob_use_embedded_server ) + { + $exe_mysql_client_test= + mtr_exe_exists("$glob_basedir/libmysqld/examples/mysql_client_test_embedded"); + } + else + { + $exe_mysql_client_test= + mtr_exe_exists("$glob_basedir/tests/mysql_client_test", + "$glob_basedir/tests/release/mysql_client_test", + "$glob_basedir/tests/debug/mysql_client_test"); + } } } @@ -1488,11 +1509,13 @@ sub environment_setup () { } $ENV{'LD_LIBRARY_PATH'}= join(":", @ld_library_paths, - split(':', qw($ENV{'LD_LIBRARY_PATH'}))); + $ENV{'LD_LIBRARY_PATHS'} ? + split(':', $ENV{'LD_LIBRARY_PATH'}) : ()); mtr_debug("LD_LIBRARY_PATH: $ENV{'LD_LIBRARY_PATH'}"); $ENV{'DYLD_LIBRARY_PATH'}= join(":", @ld_library_paths, - split(':', qw($ENV{'DYLD_LIBRARY_PATH'}))); + $ENV{'DYLD_LIBRARY_PATH'} ? + split(':', $ENV{'DYLD_LIBRARY_PATH'}) : ()); mtr_debug("DYLD_LIBRARY_PATH: $ENV{'DYLD_LIBRARY_PATH'}"); @@ -1516,29 +1539,35 @@ sub environment_setup () { $ENV{'SLAVE_MYPORT'}= $slave->[0]->{'port'}; $ENV{'SLAVE_MYPORT1'}= $slave->[1]->{'port'}; $ENV{'SLAVE_MYPORT2'}= $slave->[2]->{'port'}; - $ENV{'MYSQL_TCP_PORT'}= $default_mysqld_port; + $ENV{'MYSQL_TCP_PORT'}= $mysqld_variables{'port'}; $ENV{MTR_BUILD_THREAD}= 0 unless $ENV{MTR_BUILD_THREAD}; # Set if not set # ---------------------------------------------------- # Setup env for NDB # ---------------------------------------------------- - $ENV{'NDB_MGM'}= $exe_ndb_mgm; + if ( ! $opt_skip_ndbcluster ) + { + $ENV{'NDB_MGM'}= $exe_ndb_mgm; - $ENV{'NDBCLUSTER_PORT'}= $opt_ndbcluster_port; - $ENV{'NDBCLUSTER_PORT_SLAVE'}= $opt_ndbcluster_port_slave; + $ENV{'NDBCLUSTER_PORT'}= $opt_ndbcluster_port; + $ENV{'NDBCLUSTER_PORT_SLAVE'}= $opt_ndbcluster_port_slave; - $ENV{'NDB_EXTRA_TEST'}= $opt_ndb_extra_test; + $ENV{'NDB_EXTRA_TEST'}= $opt_ndb_extra_test; - $ENV{'NDB_BACKUP_DIR'}= $clusters->[0]->{'data_dir'}; - $ENV{'NDB_DATA_DIR'}= $clusters->[0]->{'data_dir'}; - $ENV{'NDB_TOOLS_DIR'}= $path_ndb_tools_dir; - $ENV{'NDB_TOOLS_OUTPUT'}= $path_ndb_testrun_log; - $ENV{'NDB_CONNECTSTRING'}= $opt_ndbconnectstring; + $ENV{'NDB_BACKUP_DIR'}= $clusters->[0]->{'data_dir'}; + $ENV{'NDB_DATA_DIR'}= $clusters->[0]->{'data_dir'}; + $ENV{'NDB_TOOLS_DIR'}= $path_ndb_tools_dir; + $ENV{'NDB_TOOLS_OUTPUT'}= $path_ndb_testrun_log; + $ENV{'NDB_CONNECTSTRING'}= $opt_ndbconnectstring; - $ENV{'NDB_EXAMPLES_DIR'}= $path_ndb_examples_dir; - $ENV{'MY_NDB_EXAMPLES_BINARY'}= $exe_ndb_example; - $ENV{'NDB_EXAMPLES_OUTPUT'}= $path_ndb_testrun_log; + if ( $mysql_version_id >= 50000 ) + { + $ENV{'NDB_EXAMPLES_DIR'}= $path_ndb_examples_dir; + $ENV{'MY_NDB_EXAMPLES_BINARY'}= $exe_ndb_example; + } + $ENV{'NDB_EXAMPLES_OUTPUT'}= $path_ndb_testrun_log; + } # ---------------------------------------------------- # Setup env for IM @@ -1790,7 +1819,7 @@ sub handle_int_signal () { # ############################################################################## -sub kill_running_server () { +sub kill_running_servers () { if ( $opt_fast or $glob_use_embedded_server ) { @@ -1808,6 +1837,13 @@ sub kill_running_server () { # started from this run of the script, this is terminating # leftovers from previous runs. + if ( ! -d $opt_vardir ) + { + # The "var" dir does not exist already + # the processes that mtr_kill_leftovers start will write + # their log files to var/log so it should be created + mkpath("$opt_vardir/log"); + } mtr_kill_leftovers(); } } @@ -2006,6 +2042,14 @@ sub check_ndbcluster_support ($) { } $opt_ndbcluster_supported= 1; mtr_report("Using ndbcluster when necessary, mysqld supports it"); + + if ( $mysql_version_id < 50100 ) + { + # Slave cluster is not supported until 5.1 + $opt_skip_ndbcluster_slave= 1; + + } + return; } @@ -2396,9 +2440,9 @@ sub initialize_servers () { if ( ! $glob_use_running_server ) { - kill_running_server(); + kill_running_servers(); - unless ( $opt_start_dirty ) + if ( ! $opt_start_dirty ) { cleanup_stale_files(); mysql_install_db(); @@ -2781,6 +2825,33 @@ sub do_after_run_mysqltest($) } +sub find_testcase_skipped_reason($) +{ + my ($tinfo)= @_; + + # Open mysqltest.log + my $F= IO::File->new($path_timefile) or + mtr_error("can't open file \"$path_timefile\": $!"); + my $reason; + + while ( my $line= <$F> ) + { + # Look for "reason: <reason fo skiping test>" + if ( $line =~ /reason: (.*)/ ) + { + $reason= $1; + } + } + + if ( ! $reason ) + { + mtr_warning("Could not find reason for skipping test in $path_timefile"); + $reason= "Detected by testcase(reason unknown) "; + } + $tinfo->{'comment'}= $reason; +} + + ############################################################################## # # Run a single test case @@ -2805,6 +2876,17 @@ sub run_testcase ($) { if ($master_restart or $slave_restart) { + # Can't restart a running server that may be in use + if ( $glob_use_running_server ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Can't restart a running server"; + + mtr_report_test_name($tinfo); + mtr_report_test_skipped($tinfo); + return; + } + run_testcase_stop_servers($tinfo, $master_restart, $slave_restart); } my $died= mtr_record_dead_children(); @@ -2842,10 +2924,7 @@ sub run_testcase ($) { # Testcase itself tell us to skip this one # Try to get reason from mysqltest.log - my $last_line= mtr_lastlinefromfile($path_timefile) if -f $path_timefile; - my $reason= mtr_match_prefix($last_line, "reason: "); - $tinfo->{'comment'}= - defined $reason ? $reason : "Detected by testcase(reason unknown) "; + find_testcase_skipped_reason($tinfo); mtr_report_test_skipped($tinfo); } elsif ( $res == 63 ) @@ -2872,13 +2951,10 @@ sub run_testcase ($) { # ---------------------------------------------------------------------- # Stop Instance Manager if we are processing an IM-test case. # ---------------------------------------------------------------------- - - if ( ! $glob_use_running_server and $tinfo->{'component_id'} eq 'im' ) + if ( $tinfo->{'component_id'} eq 'im' and + !mtr_im_stop($instance_manager, $tinfo->{'name'}) ) { - unless ( mtr_im_stop($instance_manager, $tinfo->{'name'}) ) - { - mtr_error("Failed to stop Instance Manager.") - } + mtr_error("Failed to stop Instance Manager.") } } @@ -3079,7 +3155,7 @@ sub mysqld_arguments ($$$$$) { $prefix= "--server-arg="; } else { # We can't pass embedded server --no-defaults - mtr_add_arg($args, "%s--no-defaults", $prefix); + mtr_add_arg($args, "--no-defaults"); } mtr_add_arg($args, "%s--console", $prefix); @@ -3501,51 +3577,46 @@ sub run_testcase_need_master_restart($) # We try to find out if we are to restart the master(s) my $do_restart= 0; # Assumes we don't have to - if ( $tinfo->{'master_sh'} ) + if ( $glob_use_embedded_server ) + { + mtr_verbose("Never start or restart for embedded server"); + return $do_restart; + } + elsif ( $tinfo->{'master_sh'} ) { $do_restart= 1; # Always restart if script to run - mtr_verbose("Restart because: Always restart if script to run"); + mtr_verbose("Restart master: Always restart if script to run"); + } + if ( $tinfo->{'force_restart'} ) + { + $do_restart= 1; # Always restart if --force-restart in -opt file + mtr_verbose("Restart master: Restart forced with --force-restart"); } elsif ( ! $opt_skip_ndbcluster and $tinfo->{'ndb_test'} == 0 and $clusters->[0]->{'pid'} != 0 ) { $do_restart= 1; # Restart without cluster - mtr_verbose("Restart because: Test does not need cluster"); + mtr_verbose("Restart master: Test does not need cluster"); } elsif ( ! $opt_skip_ndbcluster and $tinfo->{'ndb_test'} == 1 and $clusters->[0]->{'pid'} == 0 ) { $do_restart= 1; # Restart with cluster - mtr_verbose("Restart because: Test need cluster"); + mtr_verbose("Restart master: Test need cluster"); } elsif( $tinfo->{'component_id'} eq 'im' ) { $do_restart= 1; - mtr_verbose("Restart because: Always restart for im tests"); - } - elsif ( $master->[0]->{'running_master_is_special'} and - $master->[0]->{'running_master_is_special'}->{'timezone'} eq - $tinfo->{'timezone'} and - mtr_same_opts($master->[0]->{'running_master_is_special'}->{'master_opt'}, - $tinfo->{'master_opt'}) ) - { - # If running master was started with special settings, but - # the current test requires the same ones, we *don't* restart. - $do_restart= 0; - mtr_verbose("Skip restart: options are equal " . - join(" ", @{$tinfo->{'master_opt'}})); - } - elsif ( $tinfo->{'master_restart'} ) - { - $do_restart= 1; - mtr_verbose("Restart because: master_restart"); + mtr_verbose("Restart master: Always restart for im tests"); } - elsif ( $master->[0]->{'running_master_is_special'} ) + elsif ( $master->[0]->{'running_master_options'} and + $master->[0]->{'running_master_options'}->{'timezone'} ne + $tinfo->{'timezone'}) { $do_restart= 1; - mtr_verbose("Restart because: running_master_is_special"); + mtr_verbose("Restart master: Different timezone"); } # Check that running master was started with same options # as the current test requires @@ -3553,14 +3624,14 @@ sub run_testcase_need_master_restart($) $tinfo->{'master_opt'}) ) { $do_restart= 1; - mtr_verbose("Restart because: running with different options '" . + mtr_verbose("Restart master: running with different options '" . join(" ", @{$tinfo->{'master_opt'}}) . "' != '" . join(" ", @{$master->[0]->{'start_opts'}}) . "'" ); } elsif( ! $master->[0]->{'pid'} ) { $do_restart= 1; - mtr_verbose("Restart because: master is not started"); + mtr_verbose("Restart master: master is not started"); } return $do_restart; @@ -3573,9 +3644,14 @@ sub run_testcase_need_slave_restart($) # We try to find out if we are to restart the slaves my $do_slave_restart= 0; # Assumes we don't have to - if ( $max_slave_num == 0) + if ( $glob_use_embedded_server ) + { + mtr_verbose("Never start or restart for embedded server"); + return $do_slave_restart; + } + elsif ( $max_slave_num == 0) { - mtr_verbose("No testcase use slaves, no slave restarts"); + mtr_verbose("Skip slave restart: No testcase use slaves"); } else { @@ -3593,12 +3669,12 @@ sub run_testcase_need_slave_restart($) if ($any_slave_started) { - mtr_verbose("Any slave is started, need to restart"); + mtr_verbose("Restart slave: Slave is started, always restart"); $do_slave_restart= 1; } elsif ( $tinfo->{'slave_num'} ) { - mtr_verbose("Test need slave, check for restart"); + mtr_verbose("Restart slave: Test need slave"); $do_slave_restart= 1; } } @@ -3620,22 +3696,16 @@ sub run_testcase_need_slave_restart($) sub run_testcase_stop_servers($$$) { my ($tinfo, $do_restart, $do_slave_restart)= @_; - - if ( $glob_use_running_server || $glob_use_embedded_server ) - { - return; - } - my $pid; my %admin_pids; # hash of admin processes that requests shutdown my @kill_pids; # list of processes to shutdown/kill - # Remember if we restarted for this test case + # Remember if we restarted for this test case (count restarts) $tinfo->{'restarted'}= $do_restart; if ( $do_restart ) { - delete $master->[0]->{'running_master_is_special'}; # Forget history + delete $master->[0]->{'running_master_options'}; # Forget history # Start shutdown of all started masters foreach my $mysqld (@{$master}) @@ -3685,7 +3755,7 @@ sub run_testcase_stop_servers($$$) { if ( $do_restart || $do_slave_restart ) { - delete $slave->[0]->{'running_slave_is_special'}; # Forget history + delete $slave->[0]->{'running_slave_options'}; # Forget history # Start shutdown of all started slaves foreach my $mysqld (@{$slave}) @@ -3760,7 +3830,7 @@ sub run_testcase_stop_servers($$$) { # # run_testcase_start_servers # -# Start the servers neede by this test case +# Start the servers needed by this test case # # RETURN # 0 OK @@ -3769,18 +3839,13 @@ sub run_testcase_stop_servers($$$) { sub run_testcase_start_servers($) { my $tinfo= shift; - my $tname= $tinfo->{'name'}; - if ( $glob_use_running_server or $glob_use_embedded_server ) - { - return 0; - } - # ------------------------------------------------------- # Init variables that can change between server starts # ------------------------------------------------------- $ENV{'TZ'}= $tinfo->{'timezone'}; + mtr_verbose("Starting server with timezone: $tinfo->{'timezone'}"); if ( $tinfo->{'component_id'} eq 'mysqld' ) { @@ -3825,11 +3890,8 @@ sub run_testcase_start_servers($) { mysqld_start($master->[1],$tinfo->{'master_opt'},[]); } - if ( $tinfo->{'master_restart'} ) - { - # Save this test case information, so next can examine it - $master->[0]->{'running_master_is_special'}= $tinfo; - } + # Save this test case information, so next can examine it + $master->[0]->{'running_master_options'}= $tinfo; } elsif ( ! $opt_skip_im and $tinfo->{'component_id'} eq 'im' ) { @@ -3876,12 +3938,8 @@ sub run_testcase_start_servers($) { } } - if ( $tinfo->{'slave_restart'} ) - { - # Save this test case information, so next can examine it - $slave->[0]->{'running_slave_is_special'}= $tinfo; - } - + # Save this test case information, so next can examine it + $slave->[0]->{'running_slave_options'}= $tinfo; } # Wait for clusters to start @@ -3920,6 +3978,10 @@ sub run_testcase_start_servers($) { # Before a testcase, run in record mode, save result file to var # After testcase, run and compare with the recorded file, they should be equal! # +# RETURN VALUE +# 0 OK +# 1 Check failed +# sub run_check_testcase ($$) { my $mode= shift; @@ -3953,7 +4015,7 @@ sub run_check_testcase ($$) { my $res = mtr_run_test($exe_mysqltest,$args, "include/check-testcase.test", "", "", ""); - if ( $res == 1 and $mode = "after") + if ( $res == 1 and $mode eq "after") { mtr_run("diff",["-u", "$opt_vardir/tmp/$name.result", @@ -3964,6 +4026,7 @@ sub run_check_testcase ($$) { { mtr_error("Could not execute 'check-testcase' $mode testcase"); } + return $res; } @@ -4153,7 +4216,11 @@ sub run_mysqltest ($) { { if ($mysqld->{'pid'}) { - run_check_testcase("after", $mysqld); + if (run_check_testcase("after", $mysqld)) + { + # Check failed, mark the test case with that info + $tinfo->{'check_testcase_failed'}= 1; + } } } } diff --git a/mysql-test/r/func_compress.result b/mysql-test/r/func_compress.result index 00d5ebfc351..4a3454cf658 100644 --- a/mysql-test/r/func_compress.result +++ b/mysql-test/r/func_compress.result @@ -79,6 +79,16 @@ uncompress(a) uncompressed_length(a) NULL NULL a 1 drop table t1; +create table t1(a blob); +insert into t1 values ('0'), (NULL), ('0'); +select compress(a), compress(a) from t1; +select compress(a) is null from t1; +compress(a) is null +0 +1 +0 +drop table t1; +End of 4.1 tests create table t1 (a varchar(32) not null); insert into t1 values ('foo'); explain select * from t1 where uncompress(a) is null; diff --git a/mysql-test/r/func_date_add.result b/mysql-test/r/func_date_add.result index 841d13a6ea6..ac5709260fd 100644 --- a/mysql-test/r/func_date_add.result +++ b/mysql-test/r/func_date_add.result @@ -71,3 +71,17 @@ NULL NULL NULL drop table t1; +End of 4.1 tests +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 DAY; +CAST('2006-09-26' AS DATE) + INTERVAL 1 DAY +2006-09-27 +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 MONTH; +CAST('2006-09-26' AS DATE) + INTERVAL 1 MONTH +2006-10-26 +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR; +CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR +2007-09-26 +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK; +CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK +2006-10-03 +End of 5.0 tests diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result index 64eb6eefd1a..18908c2c46e 100644 --- a/mysql-test/r/func_sapdb.result +++ b/mysql-test/r/func_sapdb.result @@ -107,7 +107,9 @@ subtime("02:01:01.999999", "01:01:01.999999") 01:00:00.000000 select timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002"); timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002") -8807:59:59.999999 +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '8807:59:59.999999' select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002"); timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") 46:58:57.999999 @@ -219,13 +221,16 @@ SELECT TIMEDIFF(t1, t4) As ttt, TIMEDIFF(t2, t3) As qqq, TIMEDIFF(t3, t2) As eee, TIMEDIFF(t2, t4) As rrr from test; ttt qqq eee rrr -744:00:00 NULL NULL NULL -26305:01:02 22:58:58 -22:58:58 NULL --26305:01:02 -22:58:58 22:58:58 NULL +838:59:59 22:58:58 -22:58:58 NULL +-838:59:59 -22:58:58 22:58:58 NULL NULL 26:02:02 -26:02:02 NULL 00:00:00 -26:02:02 26:02:02 NULL NULL NULL NULL NULL NULL NULL NULL NULL 00:00:00 -24:00:00 24:00:00 NULL +Warnings: +Warning 1292 Truncated incorrect time value: '26305:01:02' +Warning 1292 Truncated incorrect time value: '-26305:01:02' drop table t1, test; select addtime("-01:01:01.01", "-23:59:59.1") as a; a @@ -235,7 +240,9 @@ a 10000 select microsecond(19971231235959.01) as a; a -10000 +0 +Warnings: +Warning 1292 Truncated incorrect time value: '19971231235959.01' select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a; a 1997-12-31 00:00:10.090000 diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 25c910a711a..7388ca3c2b8 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -339,7 +339,9 @@ extract(DAY_MINUTE FROM "02 10:11:12") 21011 select extract(DAY_SECOND FROM "225 10:11:12"); extract(DAY_SECOND FROM "225 10:11:12") -225101112 +8385959 +Warnings: +Warning 1292 Truncated incorrect time value: '225 10:11:12' select extract(HOUR FROM "1999-01-02 10:11:12"); extract(HOUR FROM "1999-01-02 10:11:12") 10 @@ -612,7 +614,7 @@ date_add(date,INTERVAL "1 1:1:1" DAY_SECOND) 2003-01-03 01:01:01 select date_add(date,INTERVAL "1" WEEK) from t1; date_add(date,INTERVAL "1" WEEK) -2003-01-09 00:00:00 +2003-01-09 select date_add(date,INTERVAL "1" QUARTER) from t1; date_add(date,INTERVAL "1" QUARTER) 2003-04-02 @@ -621,7 +623,7 @@ timestampadd(MINUTE, 1, date) 2003-01-02 00:01:00 select timestampadd(WEEK, 1, date) from t1; timestampadd(WEEK, 1, date) -2003-01-09 00:00:00 +2003-01-09 select timestampadd(SQL_TSI_SECOND, 1, date) from t1; timestampadd(SQL_TSI_SECOND, 1, date) 2003-01-02 00:00:01 @@ -890,6 +892,93 @@ t1 CREATE TABLE `t1` ( `from_unixtime(1) + 0` double(23,6) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +SELECT SEC_TO_TIME(3300000); +SEC_TO_TIME(3300000) +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '3300000' +SELECT SEC_TO_TIME(3300000)+0; +SEC_TO_TIME(3300000)+0 +8385959.000000 +Warnings: +Warning 1292 Truncated incorrect time value: '3300000' +SELECT SEC_TO_TIME(3600 * 4294967296); +SEC_TO_TIME(3600 * 4294967296) +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '15461882265600' +SELECT TIME_TO_SEC('916:40:00'); +TIME_TO_SEC('916:40:00') +3020399 +Warnings: +Warning 1292 Truncated incorrect time value: '916:40:00' +SELECT ADDTIME('500:00:00', '416:40:00'); +ADDTIME('500:00:00', '416:40:00') +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '916:40:00' +SELECT ADDTIME('916:40:00', '416:40:00'); +ADDTIME('916:40:00', '416:40:00') +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '916:40:00' +Warning 1292 Truncated incorrect time value: '1255:39:59' +SELECT SUBTIME('916:40:00', '416:40:00'); +SUBTIME('916:40:00', '416:40:00') +422:19:59 +Warnings: +Warning 1292 Truncated incorrect time value: '916:40:00' +SELECT SUBTIME('-916:40:00', '416:40:00'); +SUBTIME('-916:40:00', '416:40:00') +-838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '-916:40:00' +Warning 1292 Truncated incorrect time value: '-1255:39:59' +SELECT MAKETIME(916,0,0); +MAKETIME(916,0,0) +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '916:00:00' +SELECT MAKETIME(4294967296, 0, 0); +MAKETIME(4294967296, 0, 0) +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '4294967296:00:00' +SELECT MAKETIME(-4294967296, 0, 0); +MAKETIME(-4294967296, 0, 0) +-838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '-4294967296:00:00' +SELECT MAKETIME(0, 4294967296, 0); +MAKETIME(0, 4294967296, 0) +NULL +SELECT MAKETIME(0, 0, 4294967296); +MAKETIME(0, 0, 4294967296) +NULL +SELECT MAKETIME(CAST(-1 AS UNSIGNED), 0, 0); +MAKETIME(CAST(-1 AS UNSIGNED), 0, 0) +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '18446744073709551615:00:00' +SELECT EXTRACT(HOUR FROM '100000:02:03'); +EXTRACT(HOUR FROM '100000:02:03') +838 +Warnings: +Warning 1292 Truncated incorrect time value: '100000:02:03' +CREATE TABLE t1(f1 TIME); +INSERT INTO t1 VALUES('916:00:00 a'); +Warnings: +Warning 1265 Data truncated for column 'f1' at row 1 +Warning 1264 Out of range value adjusted for column 'f1' at row 1 +SELECT * FROM t1; +f1 +838:59:59 +DROP TABLE t1; +SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED)); +SEC_TO_TIME(CAST(-1 AS UNSIGNED)) +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '18446744073709551615' SET NAMES latin1; SET character_set_results = NULL; SHOW VARIABLES LIKE 'character_set_results'; diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index b4101e037f2..9c5a691d26b 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -104,6 +104,16 @@ SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` = id1 2 DROP TABLE t1, t2; +flush status; +create table t1 (c1 int) engine=innodb; +handler t1 open; +handler t1 read first; +c1 +show /*!50002 GLOBAL */ status like 'Handler_rollback'; +Variable_name Value +Handler_rollback 0 +drop table t1; +End of 4.1 tests create table t1m (a int) engine=myisam; create table t1i (a int) engine=innodb; create table t2m (a int) engine=myisam; diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index d7eb7da939d..6a065bd7332 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -178,9 +178,9 @@ t3 CREATE TABLE `t3` ( ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=(`t1`,`t2`) create table t4 (a int not null, b char(10), key(a)) engine=MERGE UNION=(t1,t2); select * from t4; -ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exists +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist alter table t4 add column c int; -ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exists +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist create database mysqltest; create table mysqltest.t6 (a int not null primary key auto_increment, message char(20)); create table t5 (a int not null, b char(20), key(a)) engine=MERGE UNION=(test.t1,mysqltest.t6); @@ -777,11 +777,11 @@ DROP TABLE t1, t2; CREATE TABLE t1(a INT) ENGINE=MEMORY; CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t1); SELECT * FROM t2; -ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exists +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist DROP TABLE t1, t2; CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t3); SELECT * FROM t2; -ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exists +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist DROP TABLE t2; create table t1 (b bit(1)); create table t2 (b bit(1)); diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 1053b1918fb..86ac7a8d72d 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -149,4 +149,17 @@ ERROR at line 1: USE must be followed by a database name \\ '; '; +create table t17583 (a int); +insert into t17583 (a) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +select count(*) from t17583; +count(*) +1280 +drop table t17583; End of 5.0 tests diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 7bdfa78066c..762019be313 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -520,6 +520,7 @@ t1 NULL NULL NULL NULL # # # # NULL NULL NULL NULL NULL NULL NULL NULL Incorrect show create table t1; ERROR HY000: Incorrect information in file: './test/t1.frm' drop table t1; +End of 4.1 tests CREATE TABLE txt1(a int); CREATE TABLE tyt2(a int); CREATE TABLE urkunde(a int); @@ -629,3 +630,4 @@ SHOW TABLES FROM no_such_database; ERROR 42000: Unknown database 'no_such_database' SHOW COLUMNS FROM no_such_table; ERROR 42S02: Table 'test.no_such_table' doesn't exist +End of 5.0 tests diff --git a/mysql-test/t/bdb-alter-table-2-master.opt b/mysql-test/t/bdb-alter-table-2-master.opt index 15ad73c500f..c2dca33445b 100644 --- a/mysql-test/t/bdb-alter-table-2-master.opt +++ b/mysql-test/t/bdb-alter-table-2-master.opt @@ -1,2 +1,2 @@ ---skip-external-locking +--force-restart diff --git a/mysql-test/t/func_compress.test b/mysql-test/t/func_compress.test index eeb5d509b94..68f07f258bf 100644 --- a/mysql-test/t/func_compress.test +++ b/mysql-test/t/func_compress.test @@ -56,7 +56,19 @@ insert into t1 values(NULL), (compress('a')); select uncompress(a), uncompressed_length(a) from t1; drop table t1; -# End of 4.1 tests +# +# Bug #23254: problem with compress(NULL) +# + +create table t1(a blob); +insert into t1 values ('0'), (NULL), ('0'); +--disable_result_log +select compress(a), compress(a) from t1; +--enable_result_log +select compress(a) is null from t1; +drop table t1; + +--echo End of 4.1 tests # # Bug #18539: uncompress(d) is null: impossible? diff --git a/mysql-test/t/func_date_add.test b/mysql-test/t/func_date_add.test index e01fce30577..b575eeececa 100644 --- a/mysql-test/t/func_date_add.test +++ b/mysql-test/t/func_date_add.test @@ -64,4 +64,17 @@ insert into t1 values (date_add('2000-01-04', INTERVAL NULL DAY)); select * from t1; drop table t1; -# End of 4.1 tests +--echo End of 4.1 tests + +# +# Bug#21811 +# +# Make sure we end up with an appropriate +# date format (DATE) after addition operation +# +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 DAY; +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 MONTH; +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR; +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK; + +--echo End of 5.0 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 2b3fb86829d..ae3811a3257 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -447,6 +447,47 @@ show create table t1; drop table t1; # +# Bug #11655: Wrong time is returning from nested selects - maximum time exists +# +# check if SEC_TO_TIME() handles out-of-range values correctly +SELECT SEC_TO_TIME(3300000); +SELECT SEC_TO_TIME(3300000)+0; +SELECT SEC_TO_TIME(3600 * 4294967296); + +# check if TIME_TO_SEC() handles out-of-range values correctly +SELECT TIME_TO_SEC('916:40:00'); + +# check if ADDTIME() handles out-of-range values correctly +SELECT ADDTIME('500:00:00', '416:40:00'); +SELECT ADDTIME('916:40:00', '416:40:00'); + +# check if SUBTIME() handles out-of-range values correctly +SELECT SUBTIME('916:40:00', '416:40:00'); +SELECT SUBTIME('-916:40:00', '416:40:00'); + +# check if MAKETIME() handles out-of-range values correctly +SELECT MAKETIME(916,0,0); +SELECT MAKETIME(4294967296, 0, 0); +SELECT MAKETIME(-4294967296, 0, 0); +SELECT MAKETIME(0, 4294967296, 0); +SELECT MAKETIME(0, 0, 4294967296); +SELECT MAKETIME(CAST(-1 AS UNSIGNED), 0, 0); + +# check if EXTRACT() handles out-of-range values correctly +SELECT EXTRACT(HOUR FROM '100000:02:03'); + +# check if we get proper warnings if both input string truncation +# and out-of-range value occur +CREATE TABLE t1(f1 TIME); +INSERT INTO t1 VALUES('916:00:00 a'); +SELECT * FROM t1; +DROP TABLE t1; + +# +# Bug #20927: sec_to_time treats big unsigned as signed +# +# check if SEC_TO_TIME() handles BIGINT UNSIGNED values correctly +SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED)); # 21913: DATE_FORMAT() Crashes mysql server if I use it through # mysql-connector-j driver. # diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index 59dbe5e96d4..31f626ae69d 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -117,6 +117,22 @@ INSERT INTO `t2`(`id1`,`id2`,`id3`,`id4`) VALUES SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` = 1 AND `id3` = 2); DROP TABLE t1, t2; +# Bug #22728 - Handler_rollback value is growing +# +flush status; +create table t1 (c1 int) engine=innodb; +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); +connection con2; +handler t1 open; +handler t1 read first; +disconnect con2; +connection con1; +show /*!50002 GLOBAL */ status like 'Handler_rollback'; +connection default; +drop table t1; +disconnect con1; +--echo End of 4.1 tests # # Bug #12882 min/max inconsistent on empty table # diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index f3296e6f706..6b2c84f880a 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -153,4 +153,21 @@ drop table t1; --exec echo "SELECT '\';';" >> $MYSQLTEST_VARDIR/tmp/bug20103.sql --exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20103.sql 2>&1 +# +# Bug#17583: mysql drops connection when stdout is not writable +# +create table t17583 (a int); +insert into t17583 (a) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +# Close to the minimal data needed to exercise bug. +select count(*) from t17583; +--exec echo "select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; " |$MYSQL test >&- +drop table t17583; + --echo End of 5.0 tests diff --git a/mysql-test/t/not_embedded_server-master.opt b/mysql-test/t/not_embedded_server-master.opt index 35fcc5f30c6..cef79bc8585 100644 --- a/mysql-test/t/not_embedded_server-master.opt +++ b/mysql-test/t/not_embedded_server-master.opt @@ -1 +1 @@ ---loose-to-force-a-restart +--force-restart diff --git a/mysql-test/t/rpl_dual_pos_advance-master.opt b/mysql-test/t/rpl_dual_pos_advance-master.opt index 35fcc5f30c6..cef79bc8585 100644 --- a/mysql-test/t/rpl_dual_pos_advance-master.opt +++ b/mysql-test/t/rpl_dual_pos_advance-master.opt @@ -1 +1 @@ ---loose-to-force-a-restart +--force-restart diff --git a/mysql-test/t/rpl_empty_master_crash-master.opt b/mysql-test/t/rpl_empty_master_crash-master.opt new file mode 100644 index 00000000000..cef79bc8585 --- /dev/null +++ b/mysql-test/t/rpl_empty_master_crash-master.opt @@ -0,0 +1 @@ +--force-restart diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 65a81545c87..07426193dcf 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -400,7 +400,8 @@ show create table t1; drop table t1; -# End of 4.1 tests +--echo End of 4.1 tests + # # BUG 12183 - SHOW OPEN TABLES behavior doesn't match grammar # First we close all open tables with FLUSH tables and then we open some. @@ -506,4 +507,4 @@ SHOW TABLES FROM no_such_database; SHOW COLUMNS FROM no_such_table; -# End of 5.0 tests. +--echo End of 5.0 tests diff --git a/netware/BUILD/compile-netware-END b/netware/BUILD/compile-netware-END index c5c08cea908..a8d829499bd 100755 --- a/netware/BUILD/compile-netware-END +++ b/netware/BUILD/compile-netware-END @@ -15,11 +15,11 @@ if test -e "Makefile"; then make -k clean; fi rm -f */.deps/*.P rm -rf Makefile.in.bk -# Metrowerks enviornment +# Setup Metrowerks environment . $path/mwenv -# run auto tools -. $path/compile-AUTOTOOLS +# Run autotools(use BUILD/autorun.sh) +. BUILD/autorun.sh # configure ./configure $base_configs $extra_configs diff --git a/netware/BUILD/compile-netware-max b/netware/BUILD/compile-netware-max index ec737d4615c..3286c3c693b 100644..100755 --- a/netware/BUILD/compile-netware-max +++ b/netware/BUILD/compile-netware-max @@ -15,7 +15,7 @@ suffix="max" extra_configs=" \ --with-innodb \ --with-embedded-server \ - --with-openssl \ + --with-yassl \ " . $path/compile-netware-END diff --git a/netware/BUILD/compile-netware-max-debug b/netware/BUILD/compile-netware-max-debug index ea3553ae6e1..e3155cbd7d7 100644..100755 --- a/netware/BUILD/compile-netware-max-debug +++ b/netware/BUILD/compile-netware-max-debug @@ -15,7 +15,7 @@ extra_configs=" \ --with-innodb \ --with-debug=full \ --with-embedded-server \ - --with-openssl \ + --with-yassl \ " . $path/compile-netware-END diff --git a/netware/BUILD/compile-netware-src b/netware/BUILD/compile-netware-src index f4e8a53ffea..f4e8a53ffea 100644..100755 --- a/netware/BUILD/compile-netware-src +++ b/netware/BUILD/compile-netware-src diff --git a/netware/BUILD/mwenv b/netware/BUILD/mwenv index d8d53293b2c..bc797c442ab 100755 --- a/netware/BUILD/mwenv +++ b/netware/BUILD/mwenv @@ -26,8 +26,17 @@ WINE_BUILD_DIR=`echo "$BUILD_DIR" | sed 's_'$base_unix_part'/__'` WINE_BUILD_DIR="$base/$WINE_BUILD_DIR" echo "WINE_BUILD_DIR: $WINE_BUILD_DIR" -export MWCNWx86Includes="$MYDEV/libc/include;$MYDEV/fs64/headers;$MYDEV/zlib-1.2.3;$WINE_BUILD_DIR/include;$MYDEV" -export MWNWx86Libraries="$MYDEV/libc/imports;$MYDEV/mw/lib;$MYDEV/fs64/imports;$MYDEV/zlib-1.2.3;$MYDEV/openssl;$WINE_BUILD_DIR/netware/BUILD" +# Look for libc, MySQL 5.0.x uses libc-2003 by default +libcdir="$MYDEV/libc-2003" +if test ! -d $libcdir +then + # The libcdir didn't exist, set default + libc_dir="$MYDEV/libc" +fi +echo "Using libc in $libc_dir"; + +export MWCNWx86Includes="$libc_dir/include;$MYDEV/fs64/headers;$MYDEV/zlib-1.2.3;$WINE_BUILD_DIR/include;$MYDEV" +export MWNWx86Libraries="$libc_dir/imports;$MYDEV/mw/lib;$MYDEV/fs64/imports;$MYDEV/zlib-1.2.3;$MYDEV/openssl;$WINE_BUILD_DIR/netware/BUILD" export MWNWx86LibraryFiles="libcpre.o;libc.imp;netware.imp;mwcrtl.lib;mwcpp.lib;libz.a;neb.imp;zPublics.imp;knetware.imp" export WINEPATH="$MYDEV/mw/bin" @@ -46,3 +55,15 @@ export LD='mwldnlm' export LDFLAGS='-entry _LibCPrelude -exit _LibCPostlude -map -flags pseudopreemption' export RANLIB=: export STRIP=: + +# +# Check that TERM has been set to avoid problem "Error opening +# terminal: unknown" when the script is executed using non interactive ssh +# +if test -z "$TERM" -o "$TERM"=dumb +then + export TERM=linux +fi + +# Print all env. variables +export diff --git a/sql-common/client.c b/sql-common/client.c index cfd53fb1012..fc913f3f3cf 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -2369,6 +2369,8 @@ my_bool mysql_reconnect(MYSQL *mysql) { MYSQL tmp_mysql; DBUG_ENTER("mysql_reconnect"); + DBUG_ASSERT(mysql); + DBUG_PRINT("enter", ("mysql->reconnect: %d", mysql->reconnect)); if (!mysql->reconnect || (mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info) diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 93bf23ed284..fb36e5f4e54 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -465,8 +465,10 @@ err: There may be an optional [.second_part] after seconds length Length of str l_time Store result here - was_cut Set to 1 if value was cut during conversion or to 0 - otherwise. + warning Set MYSQL_TIME_WARN_TRUNCATED flag if the input string + was cut during conversion, and/or + MYSQL_TIME_WARN_OUT_OF_RANGE flag, if the value is + out of range. NOTES Because of the extra days argument, this function can only @@ -478,15 +480,16 @@ err: */ my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, - int *was_cut) + int *warning) { - long date[5],value; + ulong date[5]; + ulonglong value; const char *end=str+length, *end_of_days; my_bool found_days,found_hours; uint state; l_time->neg=0; - *was_cut= 0; + *warning= 0; for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++) length--; if (str != end && *str == '-') @@ -501,13 +504,16 @@ my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, /* Check first if this is a full TIMESTAMP */ if (length >= 12) { /* Probably full timestamp */ + int was_cut; enum enum_mysql_timestamp_type res= str_to_datetime(str, length, l_time, - (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), was_cut); + (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), &was_cut); if ((int) res >= (int) MYSQL_TIMESTAMP_ERROR) + { + if (was_cut) + *warning|= MYSQL_TIME_WARN_TRUNCATED; return res == MYSQL_TIMESTAMP_ERROR; - /* We need to restore was_cut flag since str_to_datetime can modify it */ - *was_cut= 0; + } } /* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */ @@ -587,7 +593,7 @@ fractional: if (field_length > 0) value*= (long) log_10_int[field_length]; else if (field_length < 0) - *was_cut= 1; + *warning|= MYSQL_TIME_WARN_TRUNCATED; date[4]=value; } else @@ -601,10 +607,7 @@ fractional: ((str[1] == '-' || str[1] == '+') && (end - str) > 2 && my_isdigit(&my_charset_latin1, str[2])))) - { - *was_cut= 1; return 1; - } if (internal_format_positions[7] != 255) { @@ -623,12 +626,12 @@ fractional: } } - /* Some simple checks */ - if (date[2] >= 60 || date[3] >= 60) - { - *was_cut= 1; + /* Integer overflow checks */ + if (date[0] > UINT_MAX || date[1] > UINT_MAX || + date[2] > UINT_MAX || date[3] > UINT_MAX || + date[4] > UINT_MAX) return 1; - } + l_time->year= 0; /* For protocol::store_time */ l_time->month= 0; l_time->day= date[0]; @@ -638,6 +641,10 @@ fractional: l_time->second_part= date[4]; l_time->time_type= MYSQL_TIMESTAMP_TIME; + /* Check if the value is valid and fits into TIME range */ + if (check_time_range(l_time, warning)) + return 1; + /* Check if there is garbage at end of the TIME specification */ if (str != end) { @@ -645,7 +652,7 @@ fractional: { if (!my_isspace(&my_charset_latin1,*str)) { - *was_cut= 1; + *warning|= MYSQL_TIME_WARN_TRUNCATED; break; } } while (++str != end); @@ -655,6 +662,47 @@ fractional: /* + Check 'time' value to lie in the TIME range + + SYNOPSIS: + check_time_range() + time pointer to TIME value + warning set MYSQL_TIME_WARN_OUT_OF_RANGE flag if the value is out of range + + DESCRIPTION + If the time value lies outside of the range [-838:59:59, 838:59:59], + set it to the closest endpoint of the range and set + MYSQL_TIME_WARN_OUT_OF_RANGE flag in the 'warning' variable. + + RETURN + 0 time value is valid, but was possibly truncated + 1 time value is invalid +*/ + +int check_time_range(struct st_mysql_time *time, int *warning) +{ + longlong hour; + + if (time->minute >= 60 || time->second >= 60) + return 1; + + hour= time->hour + (24*time->day); + if (hour <= TIME_MAX_HOUR && + (hour != TIME_MAX_HOUR || time->minute != TIME_MAX_MINUTE || + time->second != TIME_MAX_SECOND || !time->second_part)) + return 0; + + time->day= 0; + time->hour= TIME_MAX_HOUR; + time->minute= TIME_MAX_MINUTE; + time->second= TIME_MAX_SECOND; + time->second_part= 0; + *warning|= MYSQL_TIME_WARN_OUT_OF_RANGE; + return 0; +} + + +/* Prepare offset of system time zone from UTC for my_system_gmt_sec() func. SYNOPSIS @@ -840,7 +888,7 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type) int my_time_to_str(const MYSQL_TIME *l_time, char *to) { uint extra_hours= 0; - return my_sprintf(to, (to, "%s%02d:%02d:%02d", + return my_sprintf(to, (to, "%s%02u:%02u:%02u", (l_time->neg ? "-" : ""), extra_hours+ l_time->hour, l_time->minute, @@ -849,7 +897,7 @@ int my_time_to_str(const MYSQL_TIME *l_time, char *to) int my_date_to_str(const MYSQL_TIME *l_time, char *to) { - return my_sprintf(to, (to, "%04d-%02d-%02d", + return my_sprintf(to, (to, "%04u-%02u-%02u", l_time->year, l_time->month, l_time->day)); @@ -857,7 +905,7 @@ int my_date_to_str(const MYSQL_TIME *l_time, char *to) int my_datetime_to_str(const MYSQL_TIME *l_time, char *to) { - return my_sprintf(to, (to, "%04d-%02d-%02d %02d:%02d:%02d", + return my_sprintf(to, (to, "%04u-%02u-%02u %02u:%02u:%02u", l_time->year, l_time->month, l_time->day, diff --git a/sql/field.cc b/sql/field.cc index 9b512fc6d4b..ec97bc92d24 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4762,9 +4762,10 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) { TIME ltime; long tmp; - int error; + int error= 0; + int warning; - if (str_to_time(from, len, <ime, &error)) + if (str_to_time(from, len, <ime, &warning)) { tmp=0L; error= 2; @@ -4773,29 +4774,27 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) } else { - if (error) + if (warning & MYSQL_TIME_WARN_TRUNCATED) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, from, len, MYSQL_TIMESTAMP_TIME, 1); - - if (ltime.month) - ltime.day=0; - tmp=(ltime.day*24L+ltime.hour)*10000L+(ltime.minute*100+ltime.second); - if (tmp > 8385959) + if (warning & MYSQL_TIME_WARN_OUT_OF_RANGE) { - tmp=8385959; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, from, len, MYSQL_TIMESTAMP_TIME, !error); error= 1; } + if (ltime.month) + ltime.day=0; + tmp=(ltime.day*24L+ltime.hour)*10000L+(ltime.minute*100+ltime.second); if (error > 1) error= 2; } if (ltime.neg) tmp= -tmp; - error |= Field_time::store((longlong) tmp, FALSE); + int3store(ptr,tmp); return error; } @@ -4814,16 +4813,16 @@ int Field_time::store(double nr) { long tmp; int error= 0; - if (nr > 8385959.0) + if (nr > (double)TIME_MAX_VALUE) { - tmp=8385959L; + tmp= TIME_MAX_VALUE; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME); error= 1; } - else if (nr < -8385959.0) + else if (nr < (double)-TIME_MAX_VALUE) { - tmp= -8385959L; + tmp= -TIME_MAX_VALUE; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME); error= 1; @@ -4851,17 +4850,17 @@ int Field_time::store(longlong nr, bool unsigned_val) { long tmp; int error= 0; - if (nr < (longlong) -8385959L && !unsigned_val) + if (nr < (longlong) -TIME_MAX_VALUE && !unsigned_val) { - tmp= -8385959L; + tmp= -TIME_MAX_VALUE; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME, 1); error= 1; } - else if (nr > (longlong) 8385959 || nr < 0 && unsigned_val) + else if (nr > (longlong) TIME_MAX_VALUE || nr < 0 && unsigned_val) { - tmp=8385959L; + tmp= TIME_MAX_VALUE; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME, 1); diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index cb11d9b0452..a4f23cd3cf0 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -326,9 +326,22 @@ void ha_myisammrg::info(uint flag) if (flag & HA_STATUS_CONST) { if (table->s->key_parts && info.rec_per_key) + { +#ifdef HAVE_purify + /* + valgrind may be unhappy about it, because optimizer may access values + between file->keys and table->key_parts, that will be uninitialized. + It's safe though, because even if opimizer will decide to use a key + with such a number, it'll be an error later anyway. + */ + bzero((char*) table->key_info[0].rec_per_key, + sizeof(table->key_info[0].rec_per_key) * table->s->key_parts); +#endif memcpy((char*) table->key_info[0].rec_per_key, (char*) info.rec_per_key, - sizeof(table->key_info[0].rec_per_key)*table->s->key_parts); + sizeof(table->key_info[0].rec_per_key) * + min(file->keys, table->s->key_parts)); + } } } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 31c2f44fc3e..4f3e280fc8a 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2965,6 +2965,7 @@ String *Item_func_compress::val_str(String *str) null_value= 1; return 0; } + null_value= 0; if (res->is_empty()) return res; /* diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 48d6458bd88..be924bd3585 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -96,6 +96,125 @@ static bool make_datetime(date_time_format_types format, TIME *ltime, /* + Wrapper over make_datetime() with validation of the input TIME value + + NOTE + see make_datetime() for more information + + RETURN + 1 if there was an error during converion + 0 otherwise +*/ + +static bool make_datetime_with_warn(date_time_format_types format, TIME *ltime, + String *str) +{ + int warning= 0; + bool rc; + + if (make_datetime(format, ltime, str)) + return 1; + if (check_time_range(ltime, &warning)) + return 1; + if (!warning) + return 0; + + make_truncated_value_warning(current_thd, str->ptr(), str->length(), + MYSQL_TIMESTAMP_TIME, NullS); + return make_datetime(format, ltime, str); +} + + +/* + Wrapper over make_time() with validation of the input TIME value + + NOTE + see make_time() for more info + + RETURN + 1 if there was an error during conversion + 0 otherwise +*/ + +static bool make_time_with_warn(const DATE_TIME_FORMAT *format, + TIME *l_time, String *str) +{ + int warning= 0; + make_time(format, l_time, str); + if (check_time_range(l_time, &warning)) + return 1; + if (warning) + { + make_truncated_value_warning(current_thd, str->ptr(), str->length(), + MYSQL_TIMESTAMP_TIME, NullS); + make_time(format, l_time, str); + } + + return 0; +} + + +/* + Convert seconds to TIME value with overflow checking + + SYNOPSIS: + sec_to_time() + seconds number of seconds + unsigned_flag 1, if 'seconds' is unsigned, 0, otherwise + ltime output TIME value + + DESCRIPTION + If the 'seconds' argument is inside TIME data range, convert it to a + corresponding value. + Otherwise, truncate the resulting value to the nearest endpoint, and + produce a warning message. + + RETURN + 1 if the value was truncated during conversion + 0 otherwise +*/ + +static bool sec_to_time(longlong seconds, bool unsigned_flag, TIME *ltime) +{ + uint sec; + + bzero((char *)ltime, sizeof(*ltime)); + + if (seconds < 0) + { + if (unsigned_flag) + goto overflow; + ltime->neg= 1; + if (seconds < -3020399) + goto overflow; + seconds= -seconds; + } + else if (seconds > 3020399) + goto overflow; + + sec= (uint) ((ulonglong) seconds % 3600); + ltime->hour= (uint) (seconds/3600); + ltime->minute= sec/60; + ltime->second= sec % 60; + + return 0; + +overflow: + ltime->hour= TIME_MAX_HOUR; + ltime->minute= TIME_MAX_MINUTE; + ltime->second= TIME_MAX_SECOND; + + char buf[22]; + int len= (int)(longlong10_to_str(seconds, buf, unsigned_flag ? 10 : -10) + - buf); + make_truncated_value_warning(current_thd, buf, len, MYSQL_TIMESTAMP_TIME, + NullS); + + return 1; +} + + +/* Date formats corresponding to compound %r and %T conversion specifiers Note: We should init at least first element of "positions" array @@ -1570,8 +1689,6 @@ int Item_func_sysdate_local::save_in_field(Field *to, bool no_conversions) String *Item_func_sec_to_time::val_str(String *str) { DBUG_ASSERT(fixed == 1); - longlong seconds=(longlong) args[0]->val_int(); - uint sec; TIME ltime; if ((null_value=args[0]->null_value) || str->alloc(19)) @@ -1580,19 +1697,8 @@ String *Item_func_sec_to_time::val_str(String *str) return (String*) 0; } - ltime.neg= 0; - if (seconds < 0) - { - seconds= -seconds; - ltime.neg= 1; - } - - sec= (uint) ((ulonglong) seconds % 3600); - ltime.day= 0; - ltime.hour= (uint) (seconds/3600); - ltime.minute= sec/60; - ltime.second= sec % 60; - + sec_to_time(args[0]->val_int(), args[0]->unsigned_flag, <ime); + make_time((DATE_TIME_FORMAT *) 0, <ime, str); return str; } @@ -1601,16 +1707,15 @@ String *Item_func_sec_to_time::val_str(String *str) longlong Item_func_sec_to_time::val_int() { DBUG_ASSERT(fixed == 1); - longlong seconds=args[0]->val_int(); - longlong sign=1; + TIME ltime; + if ((null_value=args[0]->null_value)) return 0; - if (seconds < 0) - { - seconds= -seconds; - sign= -1; - } - return sign*((seconds / 3600)*10000+((seconds/60) % 60)*100+ (seconds % 60)); + + sec_to_time(args[0]->val_int(), args[0]->unsigned_flag, <ime); + + return (ltime.neg ? -1 : 1) * + ((ltime.hour)*10000 + ltime.minute*100 + ltime.second); } @@ -2151,11 +2256,15 @@ bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const (date_sub_interval == other->date_sub_interval)); } +/* + 'interval_names' reflects the order of the enumeration interval_type. + See item_timefunc.h + */ static const char *interval_names[]= { - "year", "quarter", "month", "day", "hour", - "minute", "week", "second", "microsecond", + "year", "quarter", "month", "week", "day", + "hour", "minute", "second", "microsecond", "year_month", "day_hour", "day_minute", "day_second", "hour_minute", "hour_second", "minute_second", "day_microsecond", @@ -2692,7 +2801,9 @@ String *Item_func_add_time::val_str(String *str) } if (l_time1.neg != l_time2.neg) l_sign= -l_sign; - + + bzero((char *)&l_time3, sizeof(l_time3)); + l_time3.neg= calc_time_diff(&l_time1, &l_time2, -l_sign, &seconds, µseconds); @@ -2721,9 +2832,9 @@ String *Item_func_add_time::val_str(String *str) } l_time3.hour+= days*24; - if (!make_datetime(l_time1.second_part || l_time2.second_part ? - TIME_MICROSECOND : TIME_ONLY, - &l_time3, str)) + if (!make_datetime_with_warn(l_time1.second_part || l_time2.second_part ? + TIME_MICROSECOND : TIME_ONLY, + &l_time3, str)) return str; null_date: @@ -2778,6 +2889,8 @@ String *Item_func_timediff::val_str(String *str) if (l_time1.neg != l_time2.neg) l_sign= -l_sign; + bzero((char *)&l_time3, sizeof(l_time3)); + l_time3.neg= calc_time_diff(&l_time1, &l_time2, l_sign, &seconds, µseconds); @@ -2791,9 +2904,9 @@ String *Item_func_timediff::val_str(String *str) calc_time_from_sec(&l_time3, (long) seconds, microseconds); - if (!make_datetime(l_time1.second_part || l_time2.second_part ? - TIME_MICROSECOND : TIME_ONLY, - &l_time3, str)) + if (!make_datetime_with_warn(l_time1.second_part || l_time2.second_part ? + TIME_MICROSECOND : TIME_ONLY, + &l_time3, str)) return str; null_date: @@ -2811,29 +2924,58 @@ String *Item_func_maketime::val_str(String *str) { DBUG_ASSERT(fixed == 1); TIME ltime; + bool overflow= 0; - long hour= (long) args[0]->val_int(); - long minute= (long) args[1]->val_int(); - long second= (long) args[2]->val_int(); + longlong hour= args[0]->val_int(); + longlong minute= args[1]->val_int(); + longlong second= args[2]->val_int(); if ((null_value=(args[0]->null_value || - args[1]->null_value || - args[2]->null_value || - minute > 59 || minute < 0 || - second > 59 || second < 0 || - str->alloc(19)))) + args[1]->null_value || + args[2]->null_value || + minute < 0 || minute > 59 || + second < 0 || second > 59 || + str->alloc(19)))) return 0; + bzero((char *)<ime, sizeof(ltime)); ltime.neg= 0; + + /* Check for integer overflows */ if (hour < 0) { - ltime.neg= 1; - hour= -hour; + if (args[0]->unsigned_flag) + overflow= 1; + else + ltime.neg= 1; + } + if (-hour > UINT_MAX || hour > UINT_MAX) + overflow= 1; + + if (!overflow) + { + ltime.hour= (uint) ((hour < 0 ? -hour : hour)); + ltime.minute= (uint) minute; + ltime.second= (uint) second; + } + else + { + ltime.hour= TIME_MAX_HOUR; + ltime.minute= TIME_MAX_MINUTE; + ltime.second= TIME_MAX_SECOND; + char buf[28]; + char *ptr= longlong10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10); + int len = (int)(ptr - buf) + + my_sprintf(ptr, (ptr, ":%02u:%02u", (uint)minute, (uint)second)); + make_truncated_value_warning(current_thd, buf, len, MYSQL_TIMESTAMP_TIME, + NullS); + } + + if (make_time_with_warn((DATE_TIME_FORMAT *) 0, <ime, str)) + { + null_value= 1; + return 0; } - ltime.hour= (ulong) hour; - ltime.minute= (ulong) minute; - ltime.second= (ulong) second; - make_time((DATE_TIME_FORMAT *) 0, <ime, str); return str; } @@ -3189,7 +3331,7 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date) goto null_date; null_value= 0; - bzero((char*) ltime, sizeof(ltime)); + bzero((char*) ltime, sizeof(*ltime)); date_time_format.format.str= (char*) format->ptr(); date_time_format.format.length= format->length(); if (extract_date_time(&date_time_format, val->ptr(), val->length(), diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index d5d3efeeab4..e79c62e6ffb 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -630,18 +630,21 @@ public: }; /* - The following must be sorted so that simple intervals comes first. - (get_interval_value() depends on this) + 'interval_type' must be sorted so that simple intervals comes first, + ie year, quarter, month, week, day, hour, etc. The order based on + interval size is also important and the intervals should be kept in a + large to smaller order. (get_interval_value() depends on this) */ enum interval_type { - INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_DAY, INTERVAL_HOUR, - INTERVAL_MINUTE, INTERVAL_WEEK, INTERVAL_SECOND, INTERVAL_MICROSECOND , - INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, INTERVAL_DAY_MINUTE, - INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND, - INTERVAL_MINUTE_SECOND, INTERVAL_DAY_MICROSECOND, INTERVAL_HOUR_MICROSECOND, - INTERVAL_MINUTE_MICROSECOND, INTERVAL_SECOND_MICROSECOND + INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_WEEK, + INTERVAL_DAY, INTERVAL_HOUR, INTERVAL_MINUTE, INTERVAL_SECOND, + INTERVAL_MICROSECOND, INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, + INTERVAL_DAY_MINUTE, INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE, + INTERVAL_HOUR_SECOND, INTERVAL_MINUTE_SECOND, INTERVAL_DAY_MICROSECOND, + INTERVAL_HOUR_MICROSECOND, INTERVAL_MINUTE_MICROSECOND, + INTERVAL_SECOND_MICROSECOND }; class Item_date_add_interval :public Item_date_func diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 5ed7466b0df..2b6d2b18f88 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -3813,7 +3813,7 @@ ER_WRONG_MRG_TABLE cze "V-B¹echny tabulky v MERGE tabulce nejsou definovány stejnì" dan "Tabellerne i MERGE er ikke defineret ens" nla "Niet alle tabellen in de MERGE tabel hebben identieke gedefinities" - eng "Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exists" + eng "Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist" est "Kõik tabelid MERGE tabeli määratluses ei ole identsed" fre "Toutes les tables de la table de type MERGE n'ont pas la même définition" ger "Nicht alle Tabellen in der MERGE-Tabelle sind gleich definiert" diff --git a/sql/sp.cc b/sql/sp.cc index 49dbed79fe5..34520ccaa54 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -651,6 +651,17 @@ db_drop_routine(THD *thd, int type, sp_name *name) if (table->file->delete_row(table->record[0])) ret= SP_DELETE_ROW_FAILED; } + + if (ret == SP_OK) + { + if (mysql_bin_log.is_open()) + { + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + } + close_thread_tables(thd); DBUG_RETURN(ret); } @@ -686,6 +697,17 @@ db_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) if ((table->file->update_row(table->record[1],table->record[0]))) ret= SP_WRITE_ROW_FAILED; } + + if (ret == SP_OK) + { + if (mysql_bin_log.is_open()) + { + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + } + close_thread_tables(thd); DBUG_RETURN(ret); } @@ -764,6 +786,7 @@ print_field_values(THD *thd, TABLE *table, return SP_INTERNAL_ERROR; } } + return SP_OK; } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 50cee6eeca4..724cf88d373 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2999,9 +2999,22 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, grant_option=TRUE; thd->mem_root= old_root; pthread_mutex_unlock(&acl_cache->lock); + + if (!result) /* success */ + { + if (mysql_bin_log.is_open()) + { + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + } + rw_unlock(&LOCK_grant); - if (!result) + + if (!result) /* success */ send_ok(thd); + /* Tables are automatically closed */ DBUG_RETURN(result); } @@ -3153,9 +3166,21 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, grant_option=TRUE; thd->mem_root= old_root; pthread_mutex_unlock(&acl_cache->lock); + if (!result && !no_error) + { + if (mysql_bin_log.is_open()) + { + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + } + rw_unlock(&LOCK_grant); + if (!result && !no_error) send_ok(thd); + /* Tables are automatically closed */ DBUG_RETURN(result); } @@ -3253,11 +3278,23 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, } } VOID(pthread_mutex_unlock(&acl_cache->lock)); + + if (!result) + { + if (mysql_bin_log.is_open()) + { + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + } + rw_unlock(&LOCK_grant); close_thread_tables(thd); if (!result) send_ok(thd); + DBUG_RETURN(result); } @@ -5251,6 +5288,13 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list) } VOID(pthread_mutex_unlock(&acl_cache->lock)); + + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + rw_unlock(&LOCK_grant); close_thread_tables(thd); if (result) @@ -5307,6 +5351,13 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) rebuild_check_host(); VOID(pthread_mutex_unlock(&acl_cache->lock)); + + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + rw_unlock(&LOCK_grant); close_thread_tables(thd); if (result) @@ -5376,6 +5427,13 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) rebuild_check_host(); VOID(pthread_mutex_unlock(&acl_cache->lock)); + + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + rw_unlock(&LOCK_grant); close_thread_tables(thd); if (result) @@ -5549,6 +5607,13 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) } VOID(pthread_mutex_unlock(&acl_cache->lock)); + + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + rw_unlock(&LOCK_grant); close_thread_tables(thd); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 81508e4e9be..43d09d288e5 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -585,6 +585,7 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, qinfo.db = db; qinfo.db_len = strlen(db); + /* These DDL methods and logging protected with LOCK_mysql_create_db */ mysql_bin_log.write(&qinfo); } send_ok(thd, result); @@ -656,6 +657,7 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) qinfo.db_len = strlen(db); thd->clear_error(); + /* These DDL methods and logging protected with LOCK_mysql_create_db */ mysql_bin_log.write(&qinfo); } send_ok(thd, result); @@ -779,6 +781,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) qinfo.db_len = strlen(db); thd->clear_error(); + /* These DDL methods and logging protected with LOCK_mysql_create_db */ mysql_bin_log.write(&qinfo); } thd->server_status|= SERVER_STATUS_DB_DROPPED; @@ -805,6 +808,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) tbl_name_len= strlen(tbl->table_name) + 3; if (query_pos + tbl_name_len + 1 >= query_end) { + /* These DDL methods and logging protected with LOCK_mysql_create_db */ write_to_binlog(thd, query, query_pos -1 - query, db, db_len); query_pos= query_data_start; } @@ -817,6 +821,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) if (query_pos != query_data_start) { + /* These DDL methods and logging protected with LOCK_mysql_create_db */ write_to_binlog(thd, query, query_pos -1 - query, db, db_len); } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c62c286cfdb..febe256807a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3209,6 +3209,7 @@ end_with_restore_list: /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { + /* Presumably, REPAIR and binlog writing doesn't require synchronization */ if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated @@ -3243,6 +3244,7 @@ end_with_restore_list: /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { + /* Presumably, ANALYZE and binlog writing doesn't require synchronization */ if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated @@ -3268,6 +3270,7 @@ end_with_restore_list: /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { + /* Presumably, OPTIMIZE and binlog writing doesn't require synchronization */ if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated @@ -3554,6 +3557,7 @@ end_with_restore_list: /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */ thd->options|= OPTION_STATUS_NO_TRANS_UPDATE; } + /* DDL and binlog write order protected by LOCK_open */ res= mysql_rm_table(thd, first_table, lex->drop_if_exists, lex->drop_temporary); } @@ -3842,15 +3846,9 @@ end_with_restore_list: break; if (end_active_trans(thd)) goto error; + /* Conditionally writes to binlog */ if (!(res= mysql_create_user(thd, lex->users_list))) - { - if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } send_ok(thd); - } break; } case SQLCOM_DROP_USER: @@ -3860,15 +3858,9 @@ end_with_restore_list: break; if (end_active_trans(thd)) goto error; + /* Conditionally writes to binlog */ if (!(res= mysql_drop_user(thd, lex->users_list))) - { - if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } send_ok(thd); - } break; } case SQLCOM_RENAME_USER: @@ -3878,15 +3870,9 @@ end_with_restore_list: break; if (end_active_trans(thd)) goto error; + /* Conditionally writes to binlog */ if (!(res= mysql_rename_user(thd, lex->users_list))) - { - if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } send_ok(thd); - } break; } case SQLCOM_REVOKE_ALL: @@ -3894,15 +3880,9 @@ end_with_restore_list: if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) && check_global_access(thd,CREATE_USER_ACL)) break; + /* Conditionally writes to binlog */ if (!(res = mysql_revoke_all(thd, lex->users_list))) - { - if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } send_ok(thd); - } break; } case SQLCOM_REVOKE: @@ -3961,6 +3941,7 @@ end_with_restore_list: check_grant_routine(thd, grants | GRANT_ACL, all_tables, lex->type == TYPE_ENUM_PROCEDURE, 0)) goto error; + /* Conditionally writes to binlog */ res= mysql_routine_grant(thd, all_tables, lex->type == TYPE_ENUM_PROCEDURE, lex->users_list, grants, @@ -3973,16 +3954,11 @@ end_with_restore_list: GRANT_ACL), all_tables, 0, UINT_MAX, 0)) goto error; + /* Conditionally writes to binlog */ res= mysql_table_grant(thd, all_tables, lex->users_list, lex->columns, lex->grant, lex->sql_command == SQLCOM_REVOKE); } - if (!res && mysql_bin_log.is_open()) - { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } } else { @@ -3993,16 +3969,11 @@ end_with_restore_list: goto error; } else + /* Conditionally writes to binlog */ res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant, lex->sql_command == SQLCOM_REVOKE); if (!res) { - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } if (lex->sql_command == SQLCOM_GRANT) { List_iterator <LEX_USER> str_list(lex->users_list); @@ -4040,6 +4011,7 @@ end_with_restore_list: We WANT to write and we CAN write. ! we write after unlocking the table. */ + /* Presumably, RESET and binlog writing doesn't require synchronization */ if (!lex->no_write_to_binlog && write_to_binlog) { if (mysql_bin_log.is_open()) @@ -4560,20 +4532,16 @@ end_with_restore_list: already puts on CREATE FUNCTION. */ if (lex->sql_command == SQLCOM_ALTER_PROCEDURE) + /* Conditionally writes to binlog */ result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics); else + /* Conditionally writes to binlog */ result= sp_update_function(thd, lex->spname, &lex->sp_chistics); } } switch (result) { case SP_OK: - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } send_ok(thd); break; case SP_KEY_NOT_FOUND: @@ -4618,9 +4586,11 @@ end_with_restore_list: } #endif if (lex->sql_command == SQLCOM_DROP_PROCEDURE) - result= sp_drop_procedure(thd, lex->spname); + /* Conditionally writes to binlog */ + result= sp_drop_procedure(thd, lex->spname); /* Conditionally writes to binlog */ else - result= sp_drop_function(thd, lex->spname); + /* Conditionally writes to binlog */ + result= sp_drop_function(thd, lex->spname); /* Conditionally writes to binlog */ } else { @@ -4633,6 +4603,8 @@ end_with_restore_list: { if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0, 0)) goto error; + + /* Does NOT write to binlog */ if (!(res = mysql_drop_function(thd, &lex->spname->m_name))) { send_ok(thd); @@ -4653,12 +4625,6 @@ end_with_restore_list: switch (result) { case SP_OK: - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } send_ok(thd); break; case SP_KEY_NOT_FOUND: @@ -4754,50 +4720,6 @@ end_with_restore_list: { if (end_active_trans(thd)) goto error; - - if (!(res= mysql_create_view(thd, thd->lex->create_view_mode)) && - mysql_bin_log.is_open()) - { - String buff; - const LEX_STRING command[3]= - {{(char *)STRING_WITH_LEN("CREATE ")}, - {(char *)STRING_WITH_LEN("ALTER ")}, - {(char *)STRING_WITH_LEN("CREATE OR REPLACE ")}}; - thd->clear_error(); - - buff.append(command[thd->lex->create_view_mode].str, - command[thd->lex->create_view_mode].length); - view_store_options(thd, first_table, &buff); - buff.append(STRING_WITH_LEN("VIEW ")); - /* Test if user supplied a db (ie: we did not use thd->db) */ - if (first_table->db && first_table->db[0] && - (thd->db == NULL || strcmp(first_table->db, thd->db))) - { - append_identifier(thd, &buff, first_table->db, - first_table->db_length); - buff.append('.'); - } - append_identifier(thd, &buff, first_table->table_name, - first_table->table_name_length); - if (lex->view_list.elements) - { - List_iterator_fast<LEX_STRING> names(lex->view_list); - LEX_STRING *name; - int i; - - for (i= 0; name= names++; i++) - { - buff.append(i ? ", " : "("); - append_identifier(thd, &buff, name->str, name->length); - } - buff.append(')'); - } - buff.append(STRING_WITH_LEN(" AS ")); - buff.append(first_table->source.str, first_table->source.length); - - Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE); - mysql_bin_log.write(&qinfo); - } break; } case SQLCOM_DROP_VIEW: @@ -4805,13 +4727,8 @@ end_with_restore_list: if (check_table_access(thd, DROP_ACL, all_tables, 0) || end_active_trans(thd)) goto error; - if (!(res= mysql_drop_view(thd, first_table, thd->lex->drop_mode)) && - mysql_bin_log.is_open()) - { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } + /* Conditionally writes to binlog. */ + res= mysql_drop_view(thd, first_table, thd->lex->drop_mode); break; } case SQLCOM_CREATE_TRIGGER: @@ -4819,6 +4736,7 @@ end_with_restore_list: if (end_active_trans(thd)) goto error; + /* Conditionally writes to binlog. */ res= mysql_create_or_drop_trigger(thd, all_tables, 1); /* We don't care about trigger body after this point */ @@ -4831,6 +4749,7 @@ end_with_restore_list: if (end_active_trans(thd)) goto error; + /* Conditionally writes to binlog. */ res= mysql_create_or_drop_trigger(thd, all_tables, 0); break; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 1c5be098ae0..39e58e4f8e8 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3173,6 +3173,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */ if (alter_info->tablespace_op != NO_TABLESPACE_OP) + /* Conditionally writes to binlog. */ DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, alter_info->tablespace_op)); if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) @@ -3254,10 +3255,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, !table->s->tmp_table) // no need to touch frm { error=0; + VOID(pthread_mutex_lock(&LOCK_open)); if (new_name != table_name || new_db != db) { thd->proc_info="rename"; - VOID(pthread_mutex_lock(&LOCK_open)); /* Then do a 'simple' rename of the table */ error=0; if (!access(new_name_buff,F_OK)) @@ -3279,7 +3280,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, error= -1; } } - VOID(pthread_mutex_unlock(&LOCK_open)); } if (!error) @@ -3288,16 +3288,12 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, case LEAVE_AS_IS: break; case ENABLE: - VOID(pthread_mutex_lock(&LOCK_open)); wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); - VOID(pthread_mutex_unlock(&LOCK_open)); error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); /* COND_refresh will be signaled in close_thread_tables() */ break; case DISABLE: - VOID(pthread_mutex_lock(&LOCK_open)); wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); - VOID(pthread_mutex_unlock(&LOCK_open)); error=table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); /* COND_refresh will be signaled in close_thread_tables() */ break; @@ -3327,6 +3323,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, table->file->print_error(error, MYF(0)); error= -1; } + VOID(pthread_mutex_unlock(&LOCK_open)); table_list->table=0; // For query cache query_cache_invalidate3(thd, table_list, 0); DBUG_RETURN(error); @@ -3773,6 +3770,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, my_free((gptr) new_table,MYF(0)); goto err; } + /* + Writing to the binlog does not need to be synchronized for temporary tables, + which are thread-specific. + */ if (mysql_bin_log.is_open()) { thd->clear_error(); @@ -3955,7 +3956,7 @@ end_temporary: thd->some_tables_deleted=0; DBUG_RETURN(FALSE); - err: +err: DBUG_RETURN(TRUE); } diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index c0c9c34cbeb..706cf79d1d9 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -270,8 +270,6 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) table->triggers->drop_trigger(thd, tables, &stmt_query)); end: - VOID(pthread_mutex_unlock(&LOCK_open)); - start_waiting_global_read_lock(thd); if (!result) { @@ -284,9 +282,13 @@ end: FALSE); mysql_bin_log.write(&qinfo); } + } + + VOID(pthread_mutex_unlock(&LOCK_open)); + start_waiting_global_read_lock(thd); + if (!result) send_ok(thd); - } DBUG_RETURN(result); } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index a4e05a96f9b..24577f63124 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1095,6 +1095,8 @@ multi_update::initialize_tables(JOIN *join) List<Item> temp_fields= *fields_for_table[cnt]; ORDER group; + if (ignore) + table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); if (table == main_table) // First table in join { if (safe_update_on_fly(join->join_tab, &temp_fields)) @@ -1210,7 +1212,11 @@ multi_update::~multi_update() { TABLE_LIST *table; for (table= update_tables ; table; table= table->next_local) + { table->table->no_keyread= table->table->no_cache= 0; + if (ignore) + table->table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); + } if (tmp_tables) { diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 94c5ad331dd..82acab7129e 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -212,6 +212,7 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view) SYNOPSIS mysql_create_view() thd - thread handler + views - views to create mode - VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE RETURN VALUE @@ -219,7 +220,7 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view) TRUE Error */ -bool mysql_create_view(THD *thd, +bool mysql_create_view(THD *thd, TABLE_LIST *views, enum_view_create_mode mode) { LEX *lex= thd->lex; @@ -548,6 +549,50 @@ bool mysql_create_view(THD *thd, } VOID(pthread_mutex_lock(&LOCK_open)); res= mysql_register_view(thd, view, mode); + + if (mysql_bin_log.is_open()) + { + String buff; + const LEX_STRING command[3]= + {{(char *)STRING_WITH_LEN("CREATE ")}, + {(char *)STRING_WITH_LEN("ALTER ")}, + {(char *)STRING_WITH_LEN("CREATE OR REPLACE ")}}; + + buff.append(command[thd->lex->create_view_mode].str, + command[thd->lex->create_view_mode].length); + view_store_options(thd, views, &buff); + buff.append(STRING_WITH_LEN("VIEW ")); + + /* Test if user supplied a db (ie: we did not use thd->db) */ + if (views->db && views->db[0] && + (thd->db == NULL || strcmp(views->db, thd->db))) + { + append_identifier(thd, &buff, views->db, + views->db_length); + buff.append('.'); + } + append_identifier(thd, &buff, views->table_name, + views->table_name_length); + if (lex->view_list.elements) + { + List_iterator_fast<LEX_STRING> names(lex->view_list); + LEX_STRING *name; + int i; + + for (i= 0; name= names++; i++) + { + buff.append(i ? ", " : "("); + append_identifier(thd, &buff, name->str, name->length); + } + buff.append(')'); + } + buff.append(STRING_WITH_LEN(" AS ")); + buff.append(views->source.str, views->source.length); + + Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE); + mysql_bin_log.write(&qinfo); + } + VOID(pthread_mutex_unlock(&LOCK_open)); if (view->revision != 1) query_cache_invalidate3(thd, view, 0); @@ -1306,12 +1351,12 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) char *wrong_object_db= NULL, *wrong_object_name= NULL; bool error= FALSE; + VOID(pthread_mutex_lock(&LOCK_open)); for (view= views; view; view= view->next_local) { strxnmov(path, FN_REFLEN, mysql_data_home, "/", view->db, "/", view->table_name, reg_ext, NullS); (void) unpack_filename(path, path); - VOID(pthread_mutex_lock(&LOCK_open)); type= FRMTYPE_ERROR; if (access(path, F_OK) || FRMTYPE_VIEW != (type= mysql_frm_type(thd, path, ¬_used))) @@ -1323,7 +1368,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), name); - VOID(pthread_mutex_unlock(&LOCK_open)); continue; } if (type == FRMTYPE_TABLE) @@ -1347,8 +1391,16 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) error= TRUE; query_cache_invalidate3(thd, view, 0); sp_cache_invalidate(); - VOID(pthread_mutex_unlock(&LOCK_open)); } + if (mysql_bin_log.is_open()) + { + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + + VOID(pthread_mutex_unlock(&LOCK_open)); + if (error) { DBUG_RETURN(TRUE); diff --git a/sql/sql_view.h b/sql/sql_view.h index b6c27a60eeb..a3f11f352b0 100644 --- a/sql/sql_view.h +++ b/sql/sql_view.h @@ -16,7 +16,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -bool mysql_create_view(THD *thd, +bool mysql_create_view(THD *thd, TABLE_LIST *view, enum_view_create_mode mode); bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, diff --git a/sql/time.cc b/sql/time.cc index 5069031081d..c71ea08fb77 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -254,9 +254,9 @@ my_time_t TIME_to_timestamp(THD *thd, const TIME *t, my_bool *in_dst_time_gap) bool str_to_time_with_warn(const char *str, uint length, TIME *l_time) { - int was_cut; - bool ret_val= str_to_time(str, length, l_time, &was_cut); - if (was_cut) + int warning; + bool ret_val= str_to_time(str, length, l_time, &warning); + if (ret_val || warning) make_truncated_value_warning(current_thd, str, length, MYSQL_TIMESTAMP_TIME, NullS); return ret_val; diff --git a/vio/viosocket.c b/vio/viosocket.c index 3ce1c994d79..21b3dae906a 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -33,7 +33,7 @@ int vio_read(Vio * vio, gptr buf, int size) { int r; DBUG_ENTER("vio_read"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); /* Ensure nobody uses vio_read_buff and vio_read simultaneously */ DBUG_ASSERT(vio->read_end == vio->read_pos); @@ -64,7 +64,7 @@ int vio_read_buff(Vio *vio, gptr buf, int size) int rc; #define VIO_UNBUFFERED_READ_MIN_SIZE 2048 DBUG_ENTER("vio_read_buff"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); if (vio->read_pos < vio->read_end) { @@ -102,7 +102,7 @@ int vio_write(Vio * vio, const gptr buf, int size) { int r; DBUG_ENTER("vio_write"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); #ifdef __WIN__ r = send(vio->sd, buf, size,0); #else @@ -411,7 +411,7 @@ int vio_read_pipe(Vio * vio, gptr buf, int size) { DWORD length; DBUG_ENTER("vio_read_pipe"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); if (!ReadFile(vio->hPipe, buf, size, &length, NULL)) DBUG_RETURN(-1); @@ -425,7 +425,7 @@ int vio_write_pipe(Vio * vio, const gptr buf, int size) { DWORD length; DBUG_ENTER("vio_write_pipe"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL)) DBUG_RETURN(-1); @@ -470,7 +470,7 @@ int vio_read_shared_memory(Vio * vio, gptr buf, int size) char *current_postion; DBUG_ENTER("vio_read_shared_memory"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); remain_local = size; current_postion=buf; @@ -531,7 +531,7 @@ int vio_write_shared_memory(Vio * vio, const gptr buf, int size) char *current_postion; DBUG_ENTER("vio_write_shared_memory"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); remain = size; current_postion = buf; diff --git a/vio/viossl.c b/vio/viossl.c index 180c7a50fa7..9cc4523d32e 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -82,7 +82,7 @@ int vio_ssl_read(Vio *vio, gptr buf, int size) { int r; DBUG_ENTER("vio_ssl_read"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d, ssl_: 0x%p", + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d, ssl_: 0x%lx", vio->sd, buf, size, vio->ssl_arg)); r= SSL_read((SSL*) vio->ssl_arg, buf, size); @@ -99,7 +99,7 @@ int vio_ssl_write(Vio *vio, const gptr buf, int size) { int r; DBUG_ENTER("vio_ssl_write"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); r= SSL_write((SSL*) vio->ssl_arg, buf, size); #ifndef DBUG_OFF |