diff options
115 files changed, 2459 insertions, 745 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc index b345e755483..867b2747707 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -67,6 +67,7 @@ #define MAX_COLUMNS 256 #define MAX_EMBEDDED_SERVER_ARGS 64 #define MAX_DELIMITER_LENGTH 16 +#define DEFAULT_MAX_CONN 128 /* Flags controlling send and reap */ #define QUERY_SEND_FLAG 1 @@ -75,7 +76,8 @@ enum { OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION, OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL, - OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES + OPT_MAX_CONNECT_RETRIES, OPT_MAX_CONNECTIONS, + OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES }; static int record= 0, opt_sleep= -1; @@ -88,6 +90,7 @@ const char *opt_logdir= ""; const char *opt_include= 0, *opt_charsets_dir; static int opt_port= 0; static int opt_max_connect_retries; +static int opt_max_connections= DEFAULT_MAX_CONN; static my_bool opt_compress= 0, silent= 0, verbose= 0; static my_bool debug_info_flag= 0, debug_check_flag= 0; static my_bool tty_password= 0; @@ -97,7 +100,7 @@ static my_bool sp_protocol= 0, sp_protocol_enabled= 0; static my_bool view_protocol= 0, view_protocol_enabled= 0; static my_bool cursor_protocol= 0, cursor_protocol_enabled= 0; static my_bool parsing_disabled= 0; -static my_bool display_result_vertically= FALSE, +static my_bool display_result_vertically= FALSE, display_result_lower= FALSE, display_metadata= FALSE, display_result_sorted= FALSE; static my_bool disable_query_log= 0, disable_result_log= 0; static my_bool disable_warnings= 0; @@ -132,6 +135,7 @@ struct st_block int line; /* Start line of block */ my_bool ok; /* Should block be executed */ enum block_cmd cmd; /* Command owning the block */ + char delim[MAX_DELIMITER_LENGTH]; /* Delimiter before block */ }; static struct st_block block_stack[32]; @@ -228,6 +232,8 @@ struct st_connection char *name; size_t name_len; MYSQL_STMT* stmt; + /* Set after send to disallow other queries before reap */ + my_bool pending; #ifdef EMBEDDED_LIBRARY const char *cur_query; @@ -237,7 +243,8 @@ struct st_connection int query_done; #endif /*EMBEDDED_LIBRARY*/ }; -struct st_connection connections[128]; + +struct st_connection *connections= NULL; struct st_connection* cur_con= NULL, *next_con, *connections_end; /* @@ -272,6 +279,7 @@ enum enum_commands { Q_DISABLE_ABORT_ON_ERROR, Q_ENABLE_ABORT_ON_ERROR, Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS, Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL, Q_SORTED_RESULT, + Q_LOWERCASE, Q_START_TIMER, Q_END_TIMER, Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL, Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT, @@ -283,7 +291,7 @@ enum enum_commands { Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR, Q_LIST_FILES, Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE, Q_SEND_SHUTDOWN, Q_SHUTDOWN_SERVER, - Q_MOVE_FILE, + Q_MOVE_FILE, Q_REMOVE_FILES_WILDCARD, Q_SEND_EVAL, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ @@ -346,6 +354,7 @@ const char *command_names[]= "query_vertical", "query_horizontal", "sorted_result", + "lowercase_result", "start_timer", "end_timer", "character_set", @@ -381,6 +390,8 @@ const char *command_names[]= "send_shutdown", "shutdown_server", "move_file", + "remove_files_wildcard", + "send_eval", 0 }; @@ -484,6 +495,8 @@ void free_replace(); void do_get_replace_regex(struct st_command *command); void free_replace_regex(); +/* Used by sleep */ +void check_eol_junk_line(const char *eol); void free_all_replace(){ free_replace(); @@ -1038,7 +1051,7 @@ void check_command_args(struct st_command *command, } /* Check for too many arguments passed */ ptr= command->last_argument; - while(ptr <= command->end) + while(ptr <= command->end && *ptr != '#') { if (*ptr && *ptr != ' ') die("Extra argument '%s' passed to '%.*s'", @@ -1096,6 +1109,7 @@ void close_connections() mysql_close(next_con->util_mysql); my_free(next_con->name, MYF(MY_ALLOW_ZERO_PTR)); } + my_free(connections, MYF(MY_WME)); DBUG_VOID_RETURN; } @@ -1122,7 +1136,7 @@ void close_files() 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)); + fclose(cur_file->file); } my_free((uchar*) cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR)); cur_file->file_name= 0; @@ -1136,7 +1150,8 @@ void free_used_memory() uint i; DBUG_ENTER("free_used_memory"); - close_connections(); + if (connections) + close_connections(); close_files(); hash_free(&var_hash); @@ -2444,7 +2459,7 @@ int open_file(const char *name) if (cur_file == file_stack_end) die("Source directives are nesting too deep"); cur_file++; - if (!(cur_file->file = my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0)))) + if (!(cur_file->file = fopen(buff, "rb"))) { cur_file--; die("Could not open '%s' for reading, errno: %d", buff, errno); @@ -2656,6 +2671,10 @@ void do_exec(struct st_command *command) #endif #endif + /* exec command is interpreted externally and will not take newlines */ + while(replace(&ds_cmd, "\n", 1, " ", 1) == 0) + ; + DBUG_PRINT("info", ("Executing '%s' as '%s'", command->first_argument, ds_cmd.str)); @@ -2881,6 +2900,81 @@ void do_remove_file(struct st_command *command) /* SYNOPSIS + do_remove_files_wildcard + command called command + + DESCRIPTION + remove_files_wildcard <directory> [<file_name_pattern>] + Remove the files in <directory> optionally matching <file_name_pattern> +*/ + +void do_remove_files_wildcard(struct st_command *command) +{ + int error= 0; + uint i; + MY_DIR *dir_info; + FILEINFO *file; + char dir_separator[2]; + static DYNAMIC_STRING ds_directory; + static DYNAMIC_STRING ds_wild; + static DYNAMIC_STRING ds_file_to_remove; + char dirname[FN_REFLEN]; + + const struct command_arg rm_args[] = { + { "directory", ARG_STRING, TRUE, &ds_directory, + "Directory containing files to delete" }, + { "filename", ARG_STRING, FALSE, &ds_wild, "File pattern to delete" } + }; + DBUG_ENTER("do_remove_files_wildcard"); + + check_command_args(command, command->first_argument, + rm_args, sizeof(rm_args)/sizeof(struct command_arg), + ' '); + fn_format(dirname, ds_directory.str, "", "", MY_UNPACK_FILENAME); + + DBUG_PRINT("info", ("listing directory: %s", dirname)); + /* Note that my_dir sorts the list if not given any flags */ + if (!(dir_info= my_dir(dirname, MYF(MY_DONT_SORT | MY_WANT_STAT)))) + { + error= 1; + goto end; + } + init_dynamic_string(&ds_file_to_remove, dirname, 1024, 1024); + dir_separator[0]= FN_LIBCHAR; + dir_separator[1]= 0; + dynstr_append(&ds_file_to_remove, dir_separator); + for (i= 0; i < (uint) dir_info->number_off_files; i++) + { + file= dir_info->dir_entry + i; + /* Remove only regular files, i.e. no directories etc. */ + /* if (!MY_S_ISREG(file->mystat->st_mode)) */ + /* MY_S_ISREG does not work here on Windows, just skip directories */ + if (MY_S_ISDIR(file->mystat->st_mode)) + continue; + if (ds_wild.length && + wild_compare(file->name, ds_wild.str, 0)) + continue; + ds_file_to_remove.length= ds_directory.length + 1; + ds_file_to_remove.str[ds_directory.length + 1]= 0; + dynstr_append(&ds_file_to_remove, file->name); + DBUG_PRINT("info", ("removing file: %s", ds_file_to_remove.str)); + error= my_delete(ds_file_to_remove.str, MYF(0)) != 0; + if (error) + break; + } + my_dirend(dir_info); + +end: + handle_command_error(command, error); + dynstr_free(&ds_directory); + dynstr_free(&ds_wild); + dynstr_free(&ds_file_to_remove); + DBUG_VOID_RETURN; +} + + +/* + SYNOPSIS do_copy_file command command handle @@ -3635,49 +3729,58 @@ void do_perl(struct st_command *command) sizeof(perl_args)/sizeof(struct command_arg), ' '); - /* If no delimiter was provided, use EOF */ - if (ds_delimiter.length == 0) - dynstr_set(&ds_delimiter, "EOF"); + ds_script= command->content; + /* If it hasn't been done already by a loop iteration, fill it in */ + if (! ds_script.str) + { + /* If no delimiter was provided, use EOF */ + if (ds_delimiter.length == 0) + dynstr_set(&ds_delimiter, "EOF"); - init_dynamic_string(&ds_script, "", 1024, 1024); - read_until_delimiter(&ds_script, &ds_delimiter); + init_dynamic_string(&ds_script, "", 1024, 1024); + read_until_delimiter(&ds_script, &ds_delimiter); + command->content= ds_script; + } - DBUG_PRINT("info", ("Executing perl: %s", ds_script.str)); + /* This function could be called even if "false", so check before doing */ + if (cur_block->ok) + { + DBUG_PRINT("info", ("Executing perl: %s", ds_script.str)); - /* Create temporary file name */ - if ((fd= create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"), - "tmp", O_CREAT | O_SHARE | O_RDWR, - MYF(MY_WME))) < 0) - die("Failed to create temporary file for perl command"); - my_close(fd, MYF(0)); + /* Create temporary file name */ + if ((fd= create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"), + "tmp", O_CREAT | O_SHARE | O_RDWR, + MYF(MY_WME))) < 0) + die("Failed to create temporary file for perl command"); + my_close(fd, MYF(0)); - str_to_file(temp_file_path, ds_script.str, ds_script.length); + str_to_file(temp_file_path, ds_script.str, ds_script.length); - /* Format the "perl <filename>" command */ - my_snprintf(buf, sizeof(buf), "perl %s", temp_file_path); + /* Format the "perl <filename>" command */ + my_snprintf(buf, sizeof(buf), "perl %s", temp_file_path); - if (!(res_file= popen(buf, "r")) && command->abort_on_error) - die("popen(\"%s\", \"r\") failed", buf); + if (!(res_file= popen(buf, "r")) && command->abort_on_error) + die("popen(\"%s\", \"r\") failed", buf); - while (fgets(buf, sizeof(buf), res_file)) - { - if (disable_result_log) - { - buf[strlen(buf)-1]=0; - DBUG_PRINT("exec_result",("%s", buf)); - } - else + while (fgets(buf, sizeof(buf), res_file)) { - replace_dynstr_append(&ds_res, buf); + if (disable_result_log) + { + buf[strlen(buf)-1]=0; + DBUG_PRINT("exec_result",("%s", buf)); + } + else + { + replace_dynstr_append(&ds_res, buf); + } } - } - error= pclose(res_file); + error= pclose(res_file); - /* Remove the temporary file */ - my_delete(temp_file_path, MYF(0)); + /* Remove the temporary file */ + my_delete(temp_file_path, MYF(0)); - handle_command_error(command, WEXITSTATUS(error)); - dynstr_free(&ds_script); + handle_command_error(command, WEXITSTATUS(error)); + } dynstr_free(&ds_delimiter); DBUG_VOID_RETURN; } @@ -4116,10 +4219,19 @@ int do_disable_rpl_parse(struct st_command *command __attribute__((unused))) int do_sleep(struct st_command *command, my_bool real_sleep) { int error= 0; - char *p= command->first_argument; - char *sleep_start, *sleep_end= command->end; + char *sleep_start, *sleep_end; double sleep_val; + char *p; + static DYNAMIC_STRING ds_sleep; + const struct command_arg sleep_args[] = { + { "sleep_delay", ARG_STRING, TRUE, &ds_sleep, "Number of seconds to sleep." } + }; + check_command_args(command, command->first_argument, sleep_args, + sizeof(sleep_args)/sizeof(struct command_arg), + ' '); + p= ds_sleep.str; + sleep_end= ds_sleep.str + ds_sleep.length; while (my_isspace(charset_info, *p)) p++; if (!*p) @@ -4128,11 +4240,13 @@ int do_sleep(struct st_command *command, my_bool real_sleep) /* Check that arg starts with a digit, not handled by my_strtod */ if (!my_isdigit(charset_info, *sleep_start)) die("Invalid argument to %.*s \"%s\"", command->first_word_len, - command->query,command->first_argument); + command->query, sleep_start); sleep_val= my_strtod(sleep_start, &sleep_end, &error); + check_eol_junk_line(sleep_end); if (error) die("Invalid argument to %.*s \"%s\"", command->first_word_len, command->query, command->first_argument); + dynstr_free(&ds_sleep); /* Fixed sleep time selected by --sleep option */ if (opt_sleep >= 0 && !real_sleep) @@ -4141,7 +4255,6 @@ int do_sleep(struct st_command *command, my_bool real_sleep) DBUG_PRINT("info", ("sleep_val: %f", sleep_val)); if (sleep_val) my_sleep((ulong) (sleep_val * 1000000L)); - command->last_argument= sleep_end; return 0; } @@ -4679,7 +4792,8 @@ void do_close_connection(struct st_command *command) if (con->util_mysql) mysql_close(con->util_mysql); con->util_mysql= 0; - + con->pending= FALSE; + my_free(con->name, MYF(0)); /* @@ -5013,7 +5127,7 @@ void do_connect(struct st_command *command) { if (!(con_slot= find_connection_by_name("-closed_connection-"))) die("Connection limit exhausted, you can have max %d connections", - (int) (sizeof(connections)/sizeof(struct st_connection))); + opt_max_connections); } #ifdef EMBEDDED_LIBRARY @@ -5127,6 +5241,12 @@ int do_done(struct st_command *command) } else { + if (*cur_block->delim) + { + /* Restore "old" delimiter after false if block */ + strcpy (delimiter, cur_block->delim); + delimiter_length= strlen(delimiter); + } /* Pop block from stack, goto next line */ cur_block--; parser.current_line++; @@ -5185,6 +5305,7 @@ void do_block(enum block_cmd cmd, struct st_command* command) cur_block++; cur_block->cmd= cmd; cur_block->ok= FALSE; + cur_block->delim[0]= '\0'; DBUG_VOID_RETURN; } @@ -5221,6 +5342,15 @@ void do_block(enum block_cmd cmd, struct st_command* command) if (not_expr) cur_block->ok = !cur_block->ok; + if (cur_block->ok) + { + cur_block->delim[0]= '\0'; + } else + { + /* Remember "old" delimiter if entering a false if block */ + strcpy (cur_block->delim, delimiter); + } + DBUG_PRINT("info", ("OK: %d", cur_block->ok)); var_free(&v); @@ -5323,7 +5453,7 @@ int read_line(char *buf, int size) found_eof: if (cur_file->file != stdin) { - my_fclose(cur_file->file, MYF(0)); + fclose(cur_file->file); cur_file->file= 0; } my_free((uchar*) cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR)); @@ -5746,6 +5876,10 @@ static struct my_option my_long_options[] = "Maximum number of attempts to connect to server.", (uchar**) &opt_max_connect_retries, (uchar**) &opt_max_connect_retries, 0, GET_INT, REQUIRED_ARG, 500, 1, 10000, 0, 0, 0}, + {"max-connections", OPT_MAX_CONNECTIONS, + "Max number of open connections to server", + (uchar**) &opt_max_connections, (uchar**) &opt_max_connections, 0, + GET_INT, REQUIRED_ARG, 128, 8, 5120, 0, 0, 0}, {"password", 'p', "Password to use when connecting to server.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection or 0 for default to, in " @@ -5909,7 +6043,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), fn_format(buff, argument, "", "", MY_UNPACK_FILENAME); DBUG_ASSERT(cur_file == file_stack && cur_file->file == 0); if (!(cur_file->file= - my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0)))) + fopen(buff, "rb"))) die("Could not open '%s' for reading, errno: %d", buff, errno); cur_file->file_name= my_strdup(buff, MYF(MY_FAE)); cur_file->lineno= 1; @@ -6521,8 +6655,11 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, wait_query_thread_end(cn); #endif /*EMBEDDED_LIBRARY*/ if (!(flags & QUERY_REAP_FLAG)) + { + cn->pending= TRUE; DBUG_VOID_RETURN; - + } + do { /* @@ -6611,6 +6748,7 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, end: + cn->pending= FALSE; /* We save the return code (mysql_errno(mysql)) from the last call sent to the server into the mysqltest builtin variable $mysql_errno. This @@ -7089,10 +7227,13 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) init_dynamic_string(&ds_warnings, NULL, 0, 256); + if (cn->pending && (flags & QUERY_SEND_FLAG)) + die ("Cannot run query on connection between send and reap"); + /* Evaluate query if this is an eval command */ - if (command->type == Q_EVAL) + if (command->type == Q_EVAL || command->type == Q_SEND_EVAL) { init_dynamic_string(&eval_query, "", command->query_len+256, 1024); do_eval(&eval_query, command->query, command->end, FALSE); @@ -7611,12 +7752,6 @@ int main(int argc, char **argv) /* Init expected errors */ memset(&saved_expected_errors, 0, sizeof(saved_expected_errors)); - /* Init connections */ - memset(connections, 0, sizeof(connections)); - connections_end= connections + - (sizeof(connections)/sizeof(struct st_connection)) - 1; - next_con= connections + 1; - #ifdef EMBEDDED_LIBRARY /* set appropriate stack for the 'query' threads */ (void) pthread_attr_init(&cn_thd_attrib); @@ -7643,7 +7778,14 @@ int main(int argc, char **argv) 1024, 0, 0, get_var_key, var_free, MYF(0))) die("Variable hash initialization failed"); - var_set_string("$MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION); + var_set_string("MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION); + var_set_string("MYSQL_SYSTEM_TYPE", SYSTEM_TYPE); + var_set_string("MYSQL_MACHINE_TYPE", MACHINE_TYPE); + if (sizeof(void *) == 8) { + var_set_string("MYSQL_SYSTEM_ARCHITECTURE", "64"); + } else { + var_set_string("MYSQL_SYSTEM_ARCHITECTURE", "32"); + } memset(&master_pos, 0, sizeof(master_pos)); @@ -7671,6 +7813,13 @@ int main(int argc, char **argv) verbose_msg("Tracing progress in '%s'.", progress_file.file_name()); } + /* Init connections, allocate 1 extra as buffer + 1 for default */ + connections= (struct st_connection*) + my_malloc((opt_max_connections+2) * sizeof(struct st_connection), + MYF(MY_WME | MY_ZEROFILL)); + connections_end= connections + opt_max_connections +1; + next_con= connections + 1; + var_set_int("$PS_PROTOCOL", ps_protocol); var_set_int("$SP_PROTOCOL", sp_protocol); var_set_int("$VIEW_PROTOCOL", view_protocol); @@ -7770,7 +7919,8 @@ int main(int argc, char **argv) command->type= Q_COMMENT; } - my_bool ok_to_do= cur_block->ok; + /* delimiter needs to be executed so we can continue to parse */ + my_bool ok_to_do= cur_block->ok || command->type == Q_DELIMITER; /* Some commands need to be "done" the first time if they may get re-iterated over in a true context. This can only happen if there's @@ -7831,6 +7981,7 @@ int main(int argc, char **argv) case Q_ECHO: do_echo(command); command_executed++; break; case Q_SYSTEM: do_system(command); break; case Q_REMOVE_FILE: do_remove_file(command); break; + case Q_REMOVE_FILES_WILDCARD: do_remove_files_wildcard(command); break; case Q_MKDIR: do_mkdir(command); break; case Q_RMDIR: do_rmdir(command); break; case Q_LIST_FILES: do_list_files(command); break; @@ -7867,6 +8018,13 @@ int main(int argc, char **argv) */ display_result_sorted= TRUE; break; + case Q_LOWERCASE: + /* + Turn on lowercasing of result, will be reset after next + command + */ + display_result_lower= TRUE; + break; case Q_LET: do_let(command); break; case Q_EVAL_RESULT: die("'eval_result' command is deprecated"); @@ -7916,6 +8074,7 @@ int main(int argc, char **argv) break; } case Q_SEND: + case Q_SEND_EVAL: if (!*command->first_argument) { /* @@ -8081,8 +8240,9 @@ int main(int argc, char **argv) */ free_all_replace(); - /* Also reset "sorted_result" */ + /* Also reset "sorted_result" and "lowercase"*/ display_result_sorted= FALSE; + display_result_lower= FALSE; } last_command_executed= command_executed; @@ -9422,7 +9582,7 @@ int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name) if (pa->length+length >= pa->max_length) { if (!(new_pos= (uchar*) my_realloc((uchar*) pa->str, - (uint) (pa->max_length+PS_MALLOC), + (uint) (pa->length+length+PS_MALLOC), MYF(MY_WME)))) DBUG_RETURN(1); if (new_pos != pa->str) @@ -9433,7 +9593,7 @@ int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name) char*); pa->str=new_pos; } - pa->max_length+=PS_MALLOC; + pa->max_length= pa->length+length+PS_MALLOC; } if (pa->typelib.count >= pa->max_count-1) { @@ -9486,6 +9646,18 @@ void replace_dynstr_append_mem(DYNAMIC_STRING *ds, fix_win_paths(val, len); #endif + if (display_result_lower) + { + /* Convert to lower case, and do this first */ + char lower[512]; + char *c= lower; + for (const char *v= val; *v; v++) + *c++= my_tolower(charset_info, *v); + *c= '\0'; + /* Copy from this buffer instead */ + val= lower; + } + if (glob_replace_regex) { /* Regex replace */ diff --git a/cmd-line-utils/readline/rlmbutil.h b/cmd-line-utils/readline/rlmbutil.h index dd317e2a090..6ca8fdde92b 100644 --- a/cmd-line-utils/readline/rlmbutil.h +++ b/cmd-line-utils/readline/rlmbutil.h @@ -109,8 +109,8 @@ extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int)); extern wchar_t _rl_char_value PARAMS((char *, int)); extern int _rl_walphabetic PARAMS((wchar_t)); -#define _rl_to_wupper(wc) (iswlower (wc) ? towupper (wc) : (wc)) -#define _rl_to_wlower(wc) (iswupper (wc) ? towlower (wc) : (wc)) +#define _rl_to_wupper(wc) (iswlower (wc) ? (wchar_t)towupper (wc) : (wc)) +#define _rl_to_wlower(wc) (iswupper (wc) ? (wchar_t)towlower (wc) : (wc)) #define MB_NEXTCHAR(b,s,c,f) \ ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \ diff --git a/cmd-line-utils/readline/text.c b/cmd-line-utils/readline/text.c index 272848c798c..bb0f5d97160 100644 --- a/cmd-line-utils/readline/text.c +++ b/cmd-line-utils/readline/text.c @@ -614,7 +614,7 @@ rl_arrow_keys (count, c) #ifdef HANDLE_MULTIBYTE static char pending_bytes[MB_LEN_MAX]; static int pending_bytes_length = 0; -static mbstate_t ps = {0}; +static mbstate_t ps; #endif /* Insert the character C at the current location, moving point forward. diff --git a/configure.in b/configure.in index 9600e5cc44e..45f86677a86 100644 --- a/configure.in +++ b/configure.in @@ -4,10 +4,16 @@ dnl Process this file with autoconf to produce a configure script. # Minimum Autoconf version required. AC_PREREQ(2.59) -# Remember to also update version.c in ndb. -# When changing major version number please also check switch statement -# in mysqlbinlog::check_master_version(). +dnl Various people throughout the community may parse configure.in to +dnl get the MySQL version from the source branch. If the formatting +dnl of this line is going to be changed, please announce the change to +dnl internals@lists.mysql.com in advance of pushing the change. +dnl +dnl When changing the major version number please also check the switch +dnl statement in mysqlbinlog::check_master_version(). You may also need +dnl to update version.c in ndb. AC_INIT([MySQL Server], [5.1.45], [], [mysql]) + AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM # USTAR format gives us the possibility to store longer path names in @@ -2705,7 +2711,7 @@ case $SYSTEM_TYPE in fi # if there is no readline, but we want to build with readline, we fail - if [test "$want_to_use_readline" = "yes"] && [test ! -d "./cmd-line-utils/readline"] + if [test "$want_to_use_readline" = "yes"] && [test ! -d "$srcdir/cmd-line-utils/readline"] then AC_MSG_ERROR([This commercially licensed MySQL source package can't be built with libreadline. Please use --with-libedit to use @@ -2911,17 +2917,12 @@ AC_CONFIG_COMMANDS_POST(ac_configure_args="$ac_configure_args CFLAGS='$CFLAGS' C AC_OUTPUT -echo -echo "MySQL has a Web site at http://www.mysql.com/ which carries details on the" -echo "latest release, upcoming features, and other information to make your" -echo "work or play with MySQL more productive. There you can also find" -echo "information about mailing lists for MySQL discussion." -echo -echo "Remember to check the platform specific part of the reference manual for" -echo "hints about installing MySQL on your platform. Also have a look at the" -echo "files in the Docs directory." -echo -# The following text is checked in ./Do-compile to verify that configure +# The first line "Thank you ..." is checked in ./Do-compile to verify that configure # ended sucessfully - don't remove it. +echo echo "Thank you for choosing MySQL!" echo +echo "Remember to check the platform specific part of the reference manual" +echo "for hints about installing MySQL on your platform." +echo "Also have a look at the files in the Docs directory." +echo diff --git a/extra/yassl/include/yassl_error.hpp b/extra/yassl/include/yassl_error.hpp index 63fa9a761ba..d2473fb3e2b 100644 --- a/extra/yassl/include/yassl_error.hpp +++ b/extra/yassl/include/yassl_error.hpp @@ -64,7 +64,7 @@ enum YasslError { enum Library { yaSSL_Lib = 0, CryptoLib, SocketLib }; enum { MAX_ERROR_SZ = 80 }; -void SetErrorString(YasslError, char*); +void SetErrorString(unsigned long, char*); /* remove for now, if go back to exceptions use this wrapper // Base class for all yaSSL exceptions diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index 29aa034f885..4d8b6ac69b8 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -991,7 +991,7 @@ char* ERR_error_string(unsigned long errNumber, char* buffer) static char* msg = (char*)"Please supply a buffer for error string"; if (buffer) { - SetErrorString(YasslError(errNumber), buffer); + SetErrorString(errNumber, buffer); return buffer; } diff --git a/extra/yassl/src/yassl_error.cpp b/extra/yassl/src/yassl_error.cpp index a1ef8578da6..dd30348cd93 100644 --- a/extra/yassl/src/yassl_error.cpp +++ b/extra/yassl/src/yassl_error.cpp @@ -55,7 +55,7 @@ Library Error::get_lib() const */ -void SetErrorString(YasslError error, char* buffer) +void SetErrorString(unsigned long error, char* buffer) { using namespace TaoCrypt; const int max = MAX_ERROR_SZ; // shorthand diff --git a/include/my_sys.h b/include/my_sys.h index a4ff5c30de7..59b44307b6f 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -950,7 +950,7 @@ extern my_bool resolve_charset(const char *cs_name, extern my_bool resolve_collation(const char *cl_name, CHARSET_INFO *default_cl, CHARSET_INFO **cl); - +extern void free_charsets(void); extern char *get_charsets_dir(char *buf); extern my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2); extern my_bool init_compiled_charsets(myf flags); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index f626361536f..6ea777a0702 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -211,6 +211,7 @@ void STDCALL mysql_server_end() } else { + free_charsets(); mysql_thread_end(); } diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index b1d0e85c70e..31770592d53 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -130,12 +130,12 @@ uninstall-local: # mtr - a shortcut for executing mysql-test-run.pl mtr: $(RM) -f mtr - $(LN_S) mysql-test-run.pl mtr + $(LN_S) $(srcdir)/mysql-test-run.pl mtr # mysql-test-run - a shortcut for executing mysql-test-run.pl mysql-test-run: $(RM) -f mysql-test-run - $(LN_S) mysql-test-run.pl mysql-test-run + $(LN_S) $(srcdir)/mysql-test-run.pl mysql-test-run # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/mysql-test/collections/default.daily b/mysql-test/collections/default.daily index 56714662b8f..c71297878f7 100644 --- a/mysql-test/collections/default.daily +++ b/mysql-test/collections/default.daily @@ -1 +1,7 @@ perl mysql-test-run.pl --timer --force --comment=rpl_ndb_row --vardir=var-rpl_ndb_row --suite=rpl_ndb,ndb --mysqld=--binlog-format=row --experimental=collections/default.experimental + +perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental +perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental +perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental +perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental +perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental diff --git a/mysql-test/collections/default.push b/mysql-test/collections/default.push index 0503bd49f73..77dc9a586db 100644 --- a/mysql-test/collections/default.push +++ b/mysql-test/collections/default.push @@ -1,5 +1,5 @@ -perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental -perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental -perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental -perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental -perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental +perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-ndb +perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb +perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental --skip-ndb +perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb +perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental --skip-ndb diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql index b2cc86fbd46..291c4c1cbe6 100644 --- a/mysql-test/include/mtr_warnings.sql +++ b/mysql-test/include/mtr_warnings.sql @@ -175,6 +175,19 @@ INSERT INTO global_suppressions VALUES ("Can't find file: '.\\\\test\\\\\\?{8}.frm'"), ("Slave: Unknown table 't1' Error_code: 1051"), + /* Messages from valgrind */ + ("==[0-9]*== Memcheck,"), + ("==[0-9]*== Copyright"), + ("==[0-9]*== Using"), + ("==[0-9]*== For more details"), + /* This comes with innodb plugin tests */ + ("==[0-9]*== Warning: set address range perms: large range"), + + /* valgrind warnings: invalid file descriptor -1 in syscall + write()/read(). Bug #50414 */ + ("==[0-9]*== Warning: invalid file descriptor -1 in syscall write()"), + ("==[0-9]*== Warning: invalid file descriptor -1 in syscall read()"), + /* Transient network failures that cause warnings on reconnect. BUG#47743 and BUG#47983. diff --git a/mysql-test/include/not_binlog_format_row.inc b/mysql-test/include/not_binlog_format_row.inc new file mode 100644 index 00000000000..f9354e7cd33 --- /dev/null +++ b/mysql-test/include/not_binlog_format_row.inc @@ -0,0 +1,4 @@ +if (`SELECT @@binlog_format = 'ROW'`) +{ + skip Test cannot run with binlog_format row; +} diff --git a/mysql-test/include/test_fieldsize.inc b/mysql-test/include/test_fieldsize.inc index cbe63e26318..606bc63779d 100644 --- a/mysql-test/include/test_fieldsize.inc +++ b/mysql-test/include/test_fieldsize.inc @@ -22,7 +22,7 @@ eval $test_insert; connection slave; START SLAVE; -wait_for_slave_to_stop; +--source include/wait_for_slave_sql_to_stop.inc --replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 # --query_vertical SHOW SLAVE STATUS diff --git a/mysql-test/lib/My/ConfigFactory.pm b/mysql-test/lib/My/ConfigFactory.pm index c4d68e7127c..41b595c80e8 100644 --- a/mysql-test/lib/My/ConfigFactory.pm +++ b/mysql-test/lib/My/ConfigFactory.pm @@ -357,11 +357,14 @@ sub post_check_client_group { if (IS_WINDOWS) { - # Shared memory base may or may not be defined (e.g not defined in embedded) - my $shm = $group_to_copy_from->option("shared-memory-base-name"); - if (defined $shm) + if (! $self->{ARGS}->{embedded}) { - $config->insert($client_group_name,"shared-memory-base-name", $shm->value()); + # Shared memory base may or may not be defined (e.g not defined in embedded) + my $shm = $group_to_copy_from->option("shared-memory-base-name"); + if (defined $shm) + { + $config->insert($client_group_name,"shared-memory-base-name", $shm->value()); + } } } } diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm index 7e102b628ca..bfcad910a16 100644 --- a/mysql-test/lib/My/SafeProcess.pm +++ b/mysql-test/lib/My/SafeProcess.pm @@ -81,24 +81,28 @@ sub is_child { } -# Find the safe process binary or script my @safe_process_cmd; my $safe_kill; -if (IS_WIN32PERL or IS_CYGWIN){ - # Use my_safe_process.exe - my $exe= my_find_bin(".", ["lib/My/SafeProcess", "My/SafeProcess"], - "my_safe_process"); - push(@safe_process_cmd, $exe); - - # Use my_safe_kill.exe - $safe_kill= my_find_bin(".", "lib/My/SafeProcess", "my_safe_kill"); -} -else -{ - # Use my_safe_process - my $exe= my_find_bin(".", ["lib/My/SafeProcess", "My/SafeProcess"], - "my_safe_process"); - push(@safe_process_cmd, $exe); + +# Find the safe process binary or script +sub find_bin { + if (IS_WIN32PERL or IS_CYGWIN) + { + # Use my_safe_process.exe + my $exe= my_find_bin(".", ["lib/My/SafeProcess", "My/SafeProcess"], + "my_safe_process"); + push(@safe_process_cmd, $exe); + + # Use my_safe_kill.exe + $safe_kill= my_find_bin(".", "lib/My/SafeProcess", "my_safe_kill"); + } + else + { + # Use my_safe_process + my $exe= my_find_bin(".", ["lib/My/SafeProcess", "My/SafeProcess"], + "my_safe_process"); + push(@safe_process_cmd, $exe); + } } @@ -184,63 +188,6 @@ sub run { } # -# Start a process that returns after "duration" seconds -# or when it's parent process does not exist anymore -# -sub timer { - my $class= shift; - my $duration= shift or croak "duration required"; - my $parent_pid= $$; - - my $pid= My::SafeProcess::Base::_safe_fork(); - if ($pid){ - # Parent - my $proc= bless - ({ - SAFE_PID => $pid, - SAFE_NAME => "timer", - PARENT => $$, - }, $class); - - # Put the new process in list of running - $running{$pid}= $proc; - return $proc; - } - - # Child, install signal handlers and sleep for "duration" - $SIG{INT}= 'IGNORE'; - - $SIG{TERM}= sub { - #print STDERR "timer $$: woken up, exiting!\n"; - exit(0); - }; - - $0= "safe_timer($duration)"; - - if (IS_WIN32PERL){ - # Just a thread in same process - sleep($duration); - print STDERR "timer $$: expired after $duration seconds\n"; - exit(0); - } - - my $count_down= $duration; - while($count_down--){ - - # Check that parent is still alive - if (kill(0, $parent_pid) == 0){ - #print STDERR "timer $$: parent gone, exiting!\n"; - exit(0); - } - - sleep(1); - } - print STDERR "timer $$: expired after $duration seconds\n"; - exit(0); -} - - -# # Shutdown process nicely, and wait for shutdown_timeout seconds # If processes hasn't shutdown, kill them hard and wait for return # @@ -338,12 +285,12 @@ sub start_kill { $ret= system($safe_kill, $winpid) >> 8; if ($ret == 3){ - print "Couldn't open the winpid: $winpid ", + print "Couldn't open the winpid: $winpid ". "for pid: $pid, try one more time\n"; sleep(1); $winpid= _winpid($pid); $ret= system($safe_kill, $winpid) >> 8; - print "Couldn't open the winpid: $winpid ", + print "Couldn't open the winpid: $winpid ". "for pid: $pid, continue and see what happens...\n"; } } @@ -538,6 +485,40 @@ sub wait_any { # +# Wait for any process to exit, or a timeout +# +# Returns a reference to the SafeProcess that +# exited or a pseudo-process with $proc->{timeout} == 1 +# + +sub wait_any_timeout { + my $class= shift; + my $timeout= shift; + my $proc; + my $millis=10; + + do { + ::mtr_milli_sleep($millis); + # Slowly increse interval up to max. 1 second + $millis++ if $millis < 1000; + # Return a "fake" process for timeout + if (::has_expired($timeout)) { + $proc= bless + ({ + SAFE_PID => 0, + SAFE_NAME => "timer", + timeout => 1, + }, $class); + } else { + $proc= check_any(); + } + } while (! $proc); + + return $proc; +} + + +# # Wait for all processes to exit # sub wait_all { @@ -594,7 +575,7 @@ sub self2str { sub _verbose { return unless $_verbose; - print STDERR " ## ", @_, "\n"; + print STDERR " ## ". @_. "\n"; } diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc index aa9093fb2b4..896bd599f4f 100755 --- a/mysql-test/lib/My/SafeProcess/safe_process_win.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process_win.cc @@ -186,14 +186,20 @@ int main(int argc, const char** argv ) die("No real args -> nothing to do"); /* Copy the remaining args to child_arg */ for (int j= i+1; j < argc; j++) { - if (strchr (argv[j], ' ')) { - /* Protect with "" if this arg contains a space */ - to+= _snprintf(to, child_args + sizeof(child_args) - to, - "\"%s\" ", argv[j]); - } else { - to+= _snprintf(to, child_args + sizeof(child_args) - to, - "%s ", argv[j]); - } + arg= argv[j]; + if (strchr (arg, ' ') && + arg[0] != '\"' && + arg[strlen(arg)] != '\"') + { + /* Quote arg that contains spaces and are not quoted already */ + to+= _snprintf(to, child_args + sizeof(child_args) - to, + "\"%s\" ", arg); + } + else + { + to+= _snprintf(to, child_args + sizeof(child_args) - to, + "%s ", arg); + } } break; } else { diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index ef3c2a43e87..1b6896e5a80 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -40,7 +40,6 @@ our $default_storage_engine; our $opt_with_ndbcluster_only; our $defaults_file; our $defaults_extra_file; -our $reorder= 1; our $quick_collect; sub collect_option { @@ -99,7 +98,8 @@ sub init_pattern { # ############################################################################## -sub collect_test_cases ($$) { +sub collect_test_cases ($$$) { + my $opt_reorder= shift; # True if we're reordering tests my $suites= shift; # Semicolon separated list of test suites my $opt_cases= shift; my $cases= []; # Array of hash(one hash for each testcase) @@ -118,10 +118,16 @@ sub collect_test_cases ($$) { !(IS_WINDOWS && $::opt_embedded_server) && $lib_innodb_plugin); - foreach my $suite (split(",", $suites)) + # If not reordering, we also shouldn't group by suites, unless + # no test cases were named. + # This also effects some logic in the loop following this. + if ($opt_reorder or !@$opt_cases) { - push(@$cases, collect_one_suite($suite, $opt_cases)); - last if $some_test_found; + foreach my $suite (split(",", $suites)) + { + push(@$cases, collect_one_suite($suite, $opt_cases)); + last if $some_test_found; + } } if ( @$opt_cases ) @@ -135,6 +141,7 @@ sub collect_test_cases ($$) { my ($sname, $tname, $extension)= split_testname($test_name_spec); foreach my $test ( @$cases ) { + last unless $opt_reorder; # test->{name} is always in suite.name format if ( $test->{name} =~ /.*\.$tname/ ) { @@ -144,12 +151,13 @@ sub collect_test_cases ($$) { } if ( not $found ) { + $sname= "main" if !$opt_reorder and !$sname; mtr_error("Could not find '$tname' in '$suites' suite(s)") unless $sname; - # If suite was part of name, find it there - my ($this_case) = collect_one_suite($sname, [ $tname ]); - if ($this_case) + # If suite was part of name, find it there, may come with combinations + my @this_case = collect_one_suite($sname, [ $tname ]); + if (@this_case) { - push (@$cases, $this_case); + push (@$cases, @this_case); } else { @@ -159,7 +167,7 @@ sub collect_test_cases ($$) { } } - if ( $reorder && !$quick_collect) + if ( $opt_reorder && !$quick_collect) { # Reorder the test cases in an order that will make them faster to run my %sort_criteria; diff --git a/mysql-test/lib/mtr_gprof.pl b/mysql-test/lib/mtr_gprof.pl index f6615301dd7..5820a4007b8 100644 --- a/mysql-test/lib/mtr_gprof.pl +++ b/mysql-test/lib/mtr_gprof.pl @@ -20,43 +20,20 @@ use strict; -# These are not to be prefixed with "mtr_" +sub gprof_collect ($@) { + my ($exe_mysqld, @gprof_dirs)= @_; -sub gprof_prepare (); -sub gprof_collect (); + print ("Collecting gprof reports.....\n"); -############################################################################## -# -# -# -############################################################################## - -sub gprof_prepare () { - - rmtree($::opt_gprof_dir); - mkdir($::opt_gprof_dir); -} - -# FIXME what about master1 and slave1?! -sub gprof_collect () { - - if ( -f "$::master->[0]->{'path_myddir'}/gmon.out" ) - { - # FIXME check result code?! - mtr_run("gprof", - [$::exe_master_mysqld, - "$::master->[0]->{'path_myddir'}/gmon.out"], - $::opt_gprof_master, "", "", ""); - print "Master execution profile has been saved in $::opt_gprof_master\n"; - } - if ( -f "$::slave->[0]->{'path_myddir'}/gmon.out" ) + foreach my $datadir (@gprof_dirs) { - # FIXME check result code?! - mtr_run("gprof", - [$::exe_slave_mysqld, - "$::slave->[0]->{'path_myddir'}/gmon.out"], - $::opt_gprof_slave, "", "", ""); - print "Slave execution profile has been saved in $::opt_gprof_slave\n"; + my $gprof_msg= "$datadir/gprof.msg"; + my $gprof_err= "$datadir/gprof.err"; + if ( -f "$datadir/gmon.out" ) + { + system("gprof $exe_mysqld $datadir/gmon.out 2>$gprof_err >$gprof_msg"); + print ("GPROF output in $gprof_msg, errors in $gprof_err\n"); + } } } diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl index 658eb270535..97eb693b52e 100644 --- a/mysql-test/lib/mtr_misc.pl +++ b/mysql-test/lib/mtr_misc.pl @@ -30,7 +30,9 @@ sub mtr_script_exists(@); sub mtr_file_exists(@); sub mtr_exe_exists(@); sub mtr_exe_maybe_exists(@); - +sub mtr_milli_sleep($); +sub start_timer($); +sub has_expired($); ############################################################################## # @@ -167,11 +169,18 @@ sub mtr_exe_exists (@) { } -sub mtr_milli_sleep { +sub mtr_milli_sleep ($) { die "usage: mtr_milli_sleep(milliseconds)" unless @_ == 1; my ($millis)= @_; select(undef, undef, undef, ($millis/1000)); } +# Simple functions to start and check timers (have to be actively polled) +# Timer can be "killed" by setting it to 0 + +sub start_timer ($) { return time + $_[0]; } + +sub has_expired ($) { return $_[0] && time gt $_[0]; } + 1; diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 937e19111fb..1c4b940bbee 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -69,7 +69,7 @@ sub _mtr_report_test_name ($) { $tname.= " '$tinfo->{combination}'" if defined $tinfo->{combination}; - print _name(), _timestamp(); + print _name(). _timestamp(); printf "%-40s ", $tname; my $worker = $tinfo->{worker}; printf "w$worker " if $worker; @@ -222,8 +222,8 @@ sub mtr_report_test ($) { } -sub mtr_report_stats ($;$) { - my ($tests, $dont_error)= @_; +sub mtr_report_stats ($$;$) { + my ($prefix, $tests, $dont_error)= @_; # ---------------------------------------------------------------------- # Find out how we where doing @@ -328,6 +328,9 @@ sub mtr_report_stats ($;$) { } } + # Print summary line prefix + print "$prefix: "; + # Print a list of testcases that failed if ( $tot_failed != 0 ) { @@ -387,13 +390,13 @@ sub mtr_report_stats ($;$) { ############################################################################## sub mtr_print_line () { - print '-' x 60, "\n"; + print '-' x 60 . "\n"; } sub mtr_print_thick_line { my $char= shift || '='; - print $char x 78, "\n"; + print $char x 78 . "\n"; } @@ -451,7 +454,7 @@ sub _timestamp { # Always print message to screen sub mtr_print (@) { - print _name(), join(" ", @_), "\n"; + print _name(). join(" ", @_). "\n"; } @@ -459,22 +462,22 @@ sub mtr_print (@) { sub mtr_report (@) { if (defined $verbose) { - print _name(), join(" ", @_), "\n"; + print _name(). join(" ", @_). "\n"; } } # Print warning to screen sub mtr_warning (@) { - print STDERR _name(), _timestamp(), - "mysql-test-run: WARNING: ", join(" ", @_), "\n"; + print STDERR _name(). _timestamp(). + "mysql-test-run: WARNING: ". join(" ", @_). "\n"; } # Print error to screen and then exit sub mtr_error (@) { - print STDERR _name(), _timestamp(), - "mysql-test-run: *** ERROR: ", join(" ", @_), "\n"; + print STDERR _name(). _timestamp(). + "mysql-test-run: *** ERROR: ". join(" ", @_). "\n"; if (IS_WINDOWS) { POSIX::_exit(1); @@ -489,8 +492,8 @@ sub mtr_error (@) { sub mtr_debug (@) { if ( $verbose > 2 ) { - print STDERR _name(), - _timestamp(), "####: ", join(" ", @_), "\n"; + print STDERR _name(). + _timestamp(). "####: ". join(" ", @_). "\n"; } } @@ -498,8 +501,8 @@ sub mtr_debug (@) { sub mtr_verbose (@) { if ( $verbose ) { - print STDERR _name(), _timestamp(), - "> ",join(" ", @_),"\n"; + print STDERR _name(). _timestamp(). + "> ".join(" ", @_)."\n"; } } @@ -509,8 +512,8 @@ sub mtr_verbose_restart (@) { my $proc= $server->{proc}; if ( $verbose_restart ) { - print STDERR _name(),_timestamp(), - "> Restart $proc - ",join(" ", @args),"\n"; + print STDERR _name()._timestamp(). + "> Restart $proc - ".join(" ", @args)."\n"; } } diff --git a/mysql-test/lib/mtr_stress.pl b/mysql-test/lib/mtr_stress.pl index cd5c7b0dbb7..702bc178ae5 100644 --- a/mysql-test/lib/mtr_stress.pl +++ b/mysql-test/lib/mtr_stress.pl @@ -150,7 +150,7 @@ sub run_stress_test () mtr_add_arg($args, "--verbose"); mtr_add_arg($args, "--cleanup"); mtr_add_arg($args, "--log-error-details"); - mtr_add_arg($args, "--abort-on-error"); + mtr_add_arg($args, "--abort-on-error=1"); if ( $::opt_stress_init_file ) { diff --git a/mysql-test/lib/v1/mtr_stress.pl b/mysql-test/lib/v1/mtr_stress.pl index 93b06b32c5f..40800c9729b 100644 --- a/mysql-test/lib/v1/mtr_stress.pl +++ b/mysql-test/lib/v1/mtr_stress.pl @@ -150,7 +150,7 @@ sub run_stress_test () mtr_add_arg($args, "--verbose"); mtr_add_arg($args, "--cleanup"); mtr_add_arg($args, "--log-error-details"); - mtr_add_arg($args, "--abort-on-error"); + mtr_add_arg($args, "--abort-on-error=1"); if ( $::opt_stress_init_file ) { diff --git a/mysql-test/lib/v1/mysql-test-run.pl b/mysql-test/lib/v1/mysql-test-run.pl index caece1d355d..5d06d9c4dd8 100755 --- a/mysql-test/lib/v1/mysql-test-run.pl +++ b/mysql-test/lib/v1/mysql-test-run.pl @@ -905,6 +905,11 @@ sub command_line_setup () { mtr_report("Using default engine '$used_default_engine'") if defined $used_default_engine; + if ($glob_win32 and defined $opt_mem) { + mtr_report("--mem not supported on Windows, ignored"); + $opt_mem= undef; + } + # -------------------------------------------------------------------------- # Check if we should speed up tests by trying to run on tmpfs # -------------------------------------------------------------------------- diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 58317bb9f2e..a35741bebda 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -68,8 +68,8 @@ use My::File::Path; # Patched version of File::Path use File::Basename; use File::Copy; use File::Find; -use File::Temp qw / tempdir /; -use File::Spec::Functions qw / splitdir /; +use File::Temp qw/tempdir/; +use File::Spec::Functions qw/splitdir/; use My::Platform; use My::SafeProcess; use My::ConfigFactory; @@ -87,6 +87,7 @@ use IO::Select; require "lib/mtr_process.pl"; require "lib/mtr_io.pl"; require "lib/mtr_gcov.pl"; +require "lib/mtr_gprof.pl"; require "lib/mtr_misc.pl"; $SIG{INT}= sub { mtr_error("Got ^C signal"); }; @@ -118,6 +119,8 @@ END { } } +sub env_or_val($$) { defined $ENV{$_[0]} ? $ENV{$_[0]} : $_[1] } + my $path_config_file; # The generated config file, var/my.cnf # Visual Studio produces executables in different sub-directories based on the @@ -167,6 +170,9 @@ our $opt_gcov_exe= "gcov"; our $opt_gcov_err= "mysql-test-gcov.msg"; our $opt_gcov_msg= "mysql-test-gcov.err"; +our $opt_gprof; +our %gprof_dirs; + our $glob_debugger= 0; our $opt_gdb; our $opt_client_gdb; @@ -185,7 +191,9 @@ our $opt_experimental; our $experimental_test_cases; my $baseport; +# $opt_build_thread may later be set from $opt_port_base my $opt_build_thread= $ENV{'MTR_BUILD_THREAD'} || "auto"; +my $opt_port_base= $ENV{'MTR_PORT_BASE'} || "auto"; my $build_thread= 0; my $opt_record; @@ -195,6 +203,7 @@ my $opt_skip_core; our $opt_check_testcases= 1; my $opt_mark_progress; +my $opt_max_connections; my $opt_sleep; @@ -213,7 +222,8 @@ my $start_only; my $opt_wait_all; my $opt_repeat= 1; my $opt_retry= 3; -my $opt_retry_failure= 2; +my $opt_retry_failure= env_or_val(MTR_RETRY_FAILURE => 2); +my $opt_reorder= 1; my $opt_strace_client; @@ -226,6 +236,7 @@ my @default_valgrind_args= ("--show-reachable=yes"); my @valgrind_args; my $opt_valgrind_path; my $opt_callgrind; +my %mysqld_logs; my $opt_debug_sync_timeout= 300; # Default timeout for WAIT_FOR actions. our $opt_warnings= 1; @@ -242,9 +253,9 @@ our %mysqld_variables; my $source_dist= 0; -my $opt_max_save_core= $ENV{MTR_MAX_SAVE_CORE} || 5; -my $opt_max_save_datadir= $ENV{MTR_MAX_SAVE_DATADIR} || 20; -my $opt_max_test_fail= $ENV{MTR_MAX_TEST_FAIL} || 10; +my $opt_max_save_core= env_or_val(MTR_MAX_SAVE_CORE => 5); +my $opt_max_save_datadir= env_or_val(MTR_MAX_SAVE_DATADIR => 20); +my $opt_max_test_fail= env_or_val(MTR_MAX_TEST_FAIL => 10); my $opt_parallel= $ENV{MTR_PARALLEL} || 1; @@ -265,6 +276,9 @@ sub main { command_line_setup(); + # --help will not reach here, so now it's safe to assume we have binaries + My::SafeProcess::find_bin(); + if ( $opt_gcov ) { gcov_prepare($basedir); } @@ -294,7 +308,7 @@ sub main { } mtr_report("Collecting tests..."); - my $tests= collect_test_cases($opt_suites, \@opt_cases); + my $tests= collect_test_cases($opt_reorder, $opt_suites, \@opt_cases); if ( $opt_report_features ) { # Put "report features" as the first test to run @@ -411,7 +425,7 @@ sub main { $opt_gcov_msg, $opt_gcov_err); } - mtr_report_stats($completed); + mtr_report_stats("Completed", $completed); exit(0); } @@ -435,7 +449,7 @@ sub run_test_server ($$$) { my $result; my $exe_mysqld= find_mysqld($basedir) || ""; # Used as hint to CoreDump - my $suite_timeout_proc= My::SafeProcess->timer(suite_timeout()); + my $suite_timeout= start_timer(suite_timeout()); my $s= IO::Select->new(); $s->add($server); @@ -456,7 +470,6 @@ sub run_test_server ($$$) { mtr_verbose("Child closed socket"); $s->remove($sock); if (--$childs == 0){ - $suite_timeout_proc->kill(); return $completed; } next; @@ -525,15 +538,13 @@ sub run_test_server ($$$) { if ( !$opt_force ) { # Test has failed, force is off - $suite_timeout_proc->kill(); push(@$completed, $result); return $completed; } elsif ($opt_max_test_fail > 0 and $num_failed_test >= $opt_max_test_fail) { - $suite_timeout_proc->kill(); push(@$completed, $result); - mtr_report_stats($completed, 1); + mtr_report_stats("Too many failed", $completed, 1); mtr_report("Too many tests($num_failed_test) failed!", "Terminating..."); return undef; @@ -620,9 +631,9 @@ sub run_test_server ($$$) { next; } - # Prefer same configuration - if (defined $result and - $result->{template_path} eq $t->{template_path}) + # Prefer same configuration, or just use next if --noreorder + if (!$opt_reorder or (defined $result and + $result->{template_path} eq $t->{template_path})) { #mtr_report("Test uses same config => good match"); # Test uses same config => good match @@ -663,9 +674,9 @@ sub run_test_server ($$$) { # ---------------------------------------------------- # Check if test suite timer expired # ---------------------------------------------------- - if ( ! $suite_timeout_proc->wait_one(0) ) + if ( has_expired($suite_timeout) ) { - mtr_report_stats($completed, 1); + mtr_report_stats("Timeout", $completed, 1); mtr_report("Test suite timeout! Terminating..."); return undef; } @@ -741,6 +752,12 @@ sub run_worker ($) { elsif ($line eq 'BYE'){ mtr_report("Server said BYE"); stop_all_servers($opt_shutdown_timeout); + if ($opt_valgrind_mysqld) { + valgrind_exit_reports(); + } + if ( $opt_gprof ) { + gprof_collect (find_mysqld($basedir), keys %gprof_dirs); + } exit(0); } else { @@ -783,11 +800,12 @@ sub set_vardir { sub command_line_setup { my $opt_comment; my $opt_usage; + my $opt_list_options; # Read the command line options # Note: Keep list, and the order, in sync with usage at end of this file Getopt::Long::Configure("pass_through"); - GetOptions( + my %options=( # Control what engine/variation to run 'embedded-server' => \$opt_embedded_server, 'ps-protocol' => \$opt_ps_protocol, @@ -824,6 +842,7 @@ sub command_line_setup { # Specify ports 'build-thread|mtr-build-thread=i' => \$opt_build_thread, + 'port-base|mtr-port-base=i' => \$opt_port_base, # Test case authoring 'record' => \$opt_record, @@ -854,6 +873,7 @@ sub command_line_setup { # Coverage, profiling etc 'gcov' => \$opt_gcov, + 'gprof' => \$opt_gprof, 'valgrind|valgrind-all' => \$opt_valgrind, 'valgrind-mysqltest' => \$opt_valgrind_mysqltest, 'valgrind-mysqld' => \$opt_valgrind_mysqld, @@ -884,7 +904,7 @@ sub command_line_setup { 'report-features' => \$opt_report_features, 'comment=s' => \$opt_comment, 'fast' => \$opt_fast, - 'reorder!' => \&collect_option, + 'reorder!' => \$opt_reorder, 'enable-disabled' => \&collect_option, 'verbose+' => \$opt_verbose, 'verbose-restart' => \&report_option, @@ -904,11 +924,16 @@ sub command_line_setup { 'warnings!' => \$opt_warnings, 'timestamp' => \&report_option, 'timediff' => \&report_option, + 'max-connections=i' => \$opt_max_connections, 'help|h' => \$opt_usage, - ) or usage("Can't read options"); + 'list-options' => \$opt_list_options, + ); + + GetOptions(%options) or usage("Can't read options"); usage("") if $opt_usage; + list_options(\%options) if $opt_list_options; # -------------------------------------------------------------------------- # Setup verbosity @@ -924,6 +949,11 @@ sub command_line_setup { # Find the absolute path to the test directory $glob_mysql_test_dir= cwd(); + if ($glob_mysql_test_dir =~ / /) + { + die("Working directory \"$glob_mysql_test_dir\" contains space\n". + "Bailing out, cannot function properly with space in path"); + } if (IS_CYGWIN) { # Use mixed path format i.e c:/path/to/ @@ -1076,6 +1106,21 @@ sub command_line_setup { } } + if (IS_WINDOWS and defined $opt_mem) { + mtr_report("--mem not supported on Windows, ignored"); + $opt_mem= undef; + } + + if ($opt_port_base ne "auto") + { + if (my $rem= $opt_port_base % 10) + { + mtr_warning ("Port base $opt_port_base rounded down to multiple of 10"); + $opt_port_base-= $rem; + } + $opt_build_thread= $opt_port_base / 10 - 1000; + } + # -------------------------------------------------------------------------- # Check if we should speed up tests by trying to run on tmpfs # -------------------------------------------------------------------------- @@ -1241,7 +1286,7 @@ sub command_line_setup { # -------------------------------------------------------------------------- # Gcov flag # -------------------------------------------------------------------------- - if ( $opt_gcov and ! $source_dist ) + if ( ($opt_gcov or $opt_gprof) and ! $source_dist ) { mtr_error("Coverage test needs the source - please use source dist"); } @@ -1340,8 +1385,7 @@ sub command_line_setup { push(@valgrind_args, @default_valgrind_args) unless @valgrind_args; - # Make valgrind run in quiet mode so it only print errors - push(@valgrind_args, "--quiet" ); + # Don't add --quiet; you will loose the summary reports. mtr_report("Running valgrind with options \"", join(" ", @valgrind_args), "\""); @@ -1446,6 +1490,12 @@ sub collect_mysqld_features { mtr_add_arg($args, "--verbose"); mtr_add_arg($args, "--help"); + # Need --user=root if running as *nix root user + if (!IS_WINDOWS and $> == 0) + { + mtr_add_arg($args, "--user=root"); + } + my $exe_mysqld= find_mysqld($basedir); my $cmd= join(" ", $exe_mysqld, @$args); my $list= `$cmd`; @@ -1764,11 +1814,11 @@ sub environment_setup { { push(@ld_library_paths, "$basedir/libmysql/.libs/", "$basedir/libmysql_r/.libs/", - "$basedir/zlib.libs/"); + "$basedir/zlib/.libs/"); } else { - push(@ld_library_paths, "$basedir/lib"); + push(@ld_library_paths, "$basedir/lib", "$basedir/lib/mysql"); } } @@ -2508,6 +2558,7 @@ sub create_config_file_for_extern { # binlog reads from [client] and [mysqlbinlog] [mysqlbinlog] character-sets-dir= $path_charsetsdir +local-load= $opt_tmpdir # mysql_fix_privilege_tables.sh don't read from [client] [mysql_fix_privilege_tables] @@ -2937,11 +2988,11 @@ sub check_testcase($$) # Return immediately if no check proceess was started return 0 unless ( keys %started ); - my $timeout_proc= My::SafeProcess->timer(check_timeout()); + my $timeout= start_timer(check_timeout()); while (1){ my $result; - my $proc= My::SafeProcess->wait_any(); + my $proc= My::SafeProcess->wait_any_timeout($timeout); mtr_report("Got $proc"); if ( delete $started{$proc->pid()} ) { @@ -2965,9 +3016,6 @@ sub check_testcase($$) if ( keys(%started) == 0){ # All checks completed - - $timeout_proc->kill(); - return 0; } # Wait for next process to exit @@ -3008,10 +3056,9 @@ test case was executed:\n"; } } - elsif ( $proc eq $timeout_proc ) { - $tinfo->{comment}.= "Timeout $timeout_proc for ". - "'check-testcase' expired after ".check_timeout(). - " seconds"; + elsif ( $proc->{timeout} ) { + $tinfo->{comment}.= "Timeout for 'check-testcase' expired after " + .check_timeout()." seconds"; $result= 4; } else { @@ -3026,8 +3073,6 @@ test case was executed:\n"; # Kill any check processes still running map($_->kill(), values(%started)); - $timeout_proc->kill(); - return $result; } @@ -3099,11 +3144,11 @@ sub run_on_all($$) # Return immediately if no check proceess was started return 0 unless ( keys %started ); - my $timeout_proc= My::SafeProcess->timer(check_timeout()); + my $timeout= start_timer(check_timeout()); while (1){ my $result; - my $proc= My::SafeProcess->wait_any(); + my $proc= My::SafeProcess->wait_any_timeout($timeout); mtr_report("Got $proc"); if ( delete $started{$proc->pid()} ) { @@ -3122,17 +3167,15 @@ sub run_on_all($$) if ( keys(%started) == 0){ # All completed - $timeout_proc->kill(); return 0; } # Wait for next process to exit next; } - elsif ( $proc eq $timeout_proc ) { - $tinfo->{comment}.= "Timeout $timeout_proc for '$run' ". - "expired after ". check_timeout(). - " seconds"; + elsif ($proc->{timeout}) { + $tinfo->{comment}.= "Timeout for '$run' expired after " + .check_timeout()." seconds"; } else { # Unknown process returned, most likley a crash, abort everything @@ -3144,8 +3187,6 @@ sub run_on_all($$) # Kill any check processes still running map($_->kill(), values(%started)); - $timeout_proc->kill(); - return 1; } mtr_error("INTERNAL_ERROR: run_on_all"); @@ -3252,9 +3293,11 @@ sub run_testcase ($) { mtr_verbose("Running test:", $tinfo->{name}); - # Allow only alpanumerics pluss _ - + . in combination names + # Allow only alpanumerics pluss _ - + . in combination names, + # or anything beginning with -- (the latter comes from --combination) my $combination= $tinfo->{combination}; - if ($combination && $combination !~ /^\w[-\w\.\+]+$/) + if ($combination && $combination !~ /^\w[-\w\.\+]+$/ + && $combination !~ /^--/) { mtr_error("Combination '$combination' contains illegal characters"); } @@ -3375,7 +3418,7 @@ sub run_testcase ($) { } } - my $test_timeout_proc= My::SafeProcess->timer(testcase_timeout()); + my $test_timeout= start_timer(testcase_timeout()); do_before_run_mysqltest($tinfo); @@ -3383,9 +3426,6 @@ sub run_testcase ($) { # Failed to record state of server or server crashed report_failure_and_restart($tinfo); - # Stop the test case timer - $test_timeout_proc->kill(); - return 1; } @@ -3403,20 +3443,20 @@ sub run_testcase ($) { if ($proc) { mtr_verbose ("Found exited process $proc"); - # If that was the timeout, cancel waiting - if ( $proc eq $test_timeout_proc ) - { - $keep_waiting_proc = 0; - } } else { $proc = $keep_waiting_proc; + # Also check if timer has expired, if so cancel waiting + if ( has_expired($test_timeout) ) + { + $keep_waiting_proc = 0; + } } } - else + if (! $keep_waiting_proc) { - $proc= My::SafeProcess->wait_any(); + $proc= My::SafeProcess->wait_any_timeout($test_timeout); } # Will be restored if we need to keep waiting @@ -3433,9 +3473,6 @@ sub run_testcase ($) { # ---------------------------------------------------- if ($proc eq $test) { - # Stop the test case timer - $test_timeout_proc->kill(); - my $res= $test->exit_status(); if ($res == 0 and $opt_warnings and check_warnings($tinfo) ) @@ -3492,6 +3529,14 @@ sub run_testcase ($) { run_on_all($tinfo, "analyze-$analyze"); } + # Wait a bit and see if a server died, if so report that instead + mtr_milli_sleep(100); + my $srvproc= My::SafeProcess::check_any(); + if ($srvproc && grep($srvproc eq $_, started(all_servers()))) { + $proc= $srvproc; + goto SRVDIED; + } + # Test case failure reported by mysqltest report_failure_and_restart($tinfo); } @@ -3499,7 +3544,7 @@ sub run_testcase ($) { { # mysqltest failed, probably crashed $tinfo->{comment}= - "mysqltest failed with unexpected return code $res"; + "mysqltest failed with unexpected return code $res\n"; report_failure_and_restart($tinfo); } @@ -3517,6 +3562,7 @@ sub run_testcase ($) { # ---------------------------------------------------- # Check if it was an expected crash # ---------------------------------------------------- + SRVDIED: my $check_crash = check_expected_crash_and_restart($proc); if ($check_crash) { @@ -3529,7 +3575,7 @@ sub run_testcase ($) { # ---------------------------------------------------- # Stop the test case timer # ---------------------------------------------------- - $test_timeout_proc->kill(); + $test_timeout= 0; # ---------------------------------------------------- # Check if it was a server that died @@ -3568,7 +3614,7 @@ sub run_testcase ($) { # ---------------------------------------------------- # Check if testcase timer expired # ---------------------------------------------------- - if ( $proc eq $test_timeout_proc ) + if ( $proc->{timeout} ) { my $log_file_name= $opt_vardir."/log/".$tinfo->{shortname}.".log"; $tinfo->{comment}= @@ -3690,16 +3736,24 @@ sub extract_warning_lines ($$) { ( qr/^Warning:|mysqld: Warning|\[Warning\]/, qr/^Error:|\[ERROR\]/, - qr/^==\d*==/, # valgrind errors + qr/^==\d+==\s+\S/, # valgrind errors qr/InnoDB: Warning|InnoDB: Error/, qr/^safe_mutex:|allocated at line/, qr/missing DBUG_RETURN/, qr/Attempting backtrace/, qr/Assertion .* failed/, ); + my $skip_valgrind= 0; foreach my $line ( @lines ) { + if ($opt_valgrind_mysqld) { + # Skip valgrind summary from tests where server has been restarted + # Should this contain memory leaks, the final report will find it + $skip_valgrind= 1 if $line =~ /^==\d+== ERROR SUMMARY:/; + $skip_valgrind= 0 unless $line =~ /^==\d+==/; + next if $skip_valgrind; + } foreach my $pat ( @patterns ) { if ( $line =~ /$pat/ ) @@ -3739,7 +3793,6 @@ sub start_check_warnings ($$) { mtr_add_arg($args, "--skip-safemalloc"); mtr_add_arg($args, "--test-file=%s", "include/check-warnings.test"); - mtr_add_arg($args, "--verbose"); if ( $opt_embedded_server ) { @@ -3802,11 +3855,11 @@ sub check_warnings ($) { # Return immediately if no check proceess was started return 0 unless ( keys %started ); - my $timeout_proc= My::SafeProcess->timer(check_timeout()); + my $timeout= start_timer(check_timeout()); while (1){ my $result= 0; - my $proc= My::SafeProcess->wait_any(); + my $proc= My::SafeProcess->wait_any_timeout($timeout); mtr_report("Got $proc"); if ( delete $started{$proc->pid()} ) { @@ -3835,9 +3888,6 @@ sub check_warnings ($) { if ( keys(%started) == 0){ # All checks completed - - $timeout_proc->kill(); - return $result; } # Wait for next process to exit @@ -3854,10 +3904,9 @@ sub check_warnings ($) { $result= 2; } } - elsif ( $proc eq $timeout_proc ) { - $tinfo->{comment}.= "Timeout $timeout_proc for ". - "'check warnings' expired after ".check_timeout(). - " seconds"; + elsif ( $proc->{timeout} ) { + $tinfo->{comment}.= "Timeout for 'check warnings' expired after " + .check_timeout()." seconds"; $result= 4; } else { @@ -3871,8 +3920,6 @@ sub check_warnings ($) { # Kill any check processes still running map($_->kill(), values(%started)); - $timeout_proc->kill(); - return $result; } @@ -3890,7 +3937,7 @@ sub check_expected_crash_and_restart { foreach my $mysqld ( mysqlds() ) { - next unless ( $mysqld->{proc} eq $proc ); + next unless ( $mysqld->{proc} and $mysqld->{proc} eq $proc ); # Check if crash expected by looking at the .expect file # in var/tmp @@ -4088,6 +4135,20 @@ sub report_failure_and_restart ($) { # about what failed has been saved to file. Save the report # in tinfo $tinfo->{logfile}= mtr_fromfile($logfile); + # If no newlines in the test log: + # (it will contain the CURRENT_TEST written by mtr, so is not empty) + if ($tinfo->{logfile} !~ /\n/) + { + # Show how far it got before suddenly failing + $tinfo->{comment}.= "mysqltest failed but provided no output\n"; + my $log_file_name= $opt_vardir."/log/".$tinfo->{shortname}.".log"; + if (-e $log_file_name) { + $tinfo->{comment}.= + "The result from queries just before the failure was:". + "\n< snip >\n". + mtr_lastlinesfromfile($log_file_name, 20)."\n"; + } + } } else { @@ -4297,6 +4358,10 @@ sub mysqld_start ($$) { # see the exact location where valgrind complains $output= "$opt_vardir/log/".$mysqld->name().".trace"; } + # Remember this log file for valgrind error report search + $mysqld_logs{$output}= 1 if $opt_valgrind; + # Remember data dir for gmon.out files if using gprof + $gprof_dirs{$mysqld->value('datadir')}= 1 if $opt_gprof; if ( defined $exe ) { @@ -4846,6 +4911,10 @@ sub start_mysqltest ($) { mtr_add_arg($args, "--ssl"); } + if ( $opt_max_connections ) { + mtr_add_arg($args, "--max-connections=%d", $opt_max_connections); + } + if ( $opt_embedded_server ) { @@ -4946,7 +5015,7 @@ sub gdb_arguments { my $type= shift; # Write $args to gdb init file - my $str= join(" ", @$$args); + my $str= join " ", map { s/"/\\"/g; "\"$_\""; } @$$args; my $gdb_init_file= "$opt_vardir/tmp/gdbinit.$type"; # Remove the old gdbinit file @@ -5010,7 +5079,7 @@ sub ddd_arguments { my $type= shift; # Write $args to ddd init file - my $str= join(" ", @$$args); + my $str= join " ", map { s/"/\\"/g; "\"$_\""; } @$$args; my $gdb_init_file= "$opt_vardir/tmp/gdbinit.$type"; # Remove the old gdbinit file @@ -5074,9 +5143,9 @@ sub debugger_arguments { { # vc[express] /debugexe exe arg1 .. argn - # Add /debugexe and name of the exe before args - unshift(@$$args, "/debugexe"); + # Add name of the exe and /debugexe before args unshift(@$$args, "$$exe"); + unshift(@$$args, "/debugexe"); # Set exe to debuggername $$exe= $debugger; @@ -5149,6 +5218,66 @@ sub valgrind_arguments { } } +# +# Search server logs for valgrind reports printed at mysqld termination +# + +sub valgrind_exit_reports() { + foreach my $log_file (keys %mysqld_logs) + { + my @culprits= (); + my $valgrind_rep= ""; + my $found_report= 0; + my $err_in_report= 0; + + my $LOGF = IO::File->new($log_file) + or mtr_error("Could not open file '$log_file' for reading: $!"); + + while ( my $line = <$LOGF> ) + { + if ($line =~ /^CURRENT_TEST: (.+)$/) + { + my $testname= $1; + # If we have a report, report it if needed and start new list of tests + if ($found_report) + { + if ($err_in_report) + { + mtr_print ("Valgrind report from $log_file after tests:\n", + @culprits); + mtr_print_line(); + print ("$valgrind_rep\n"); + $err_in_report= 0; + } + # Make ready to collect new report + @culprits= (); + $found_report= 0; + $valgrind_rep= ""; + } + push (@culprits, $testname); + next; + } + # This line marks the start of a valgrind report + $found_report= 1 if $line =~ /ERROR SUMMARY:/; + + if ($found_report) { + $line=~ s/^==\d+== //; + $valgrind_rep .= $line; + $err_in_report= 1 if $line =~ /ERROR SUMMARY: [1-9]/; + $err_in_report= 1 if $line =~ /definitely lost: [1-9]/; + $err_in_report= 1 if $line =~ /possibly lost: [1-9]/; + } + } + + $LOGF= undef; + + if ($err_in_report) { + mtr_print ("Valgrind report from $log_file after tests:\n", @culprits); + mtr_print_line(); + print ("$valgrind_rep\n"); + } + } +} # # Usage @@ -5228,6 +5357,11 @@ Options to control what test suites or cases to run Options that specify ports + mtr-port-base=# Base for port numbers, ports from this number to + port-base=# number+9 are reserved. Should be divisible by 10; + if not it will be rounded down. May be set with + environment variable MTR_PORT_BASE. If this value is + set and is not "auto", it overrides build-thread. mtr-build-thread=# Specify unique number to calculate port number(s) from. build-thread=# Can be set in environment variable MTR_BUILD_THREAD. Set MTR_BUILD_THREAD="auto" to automatically aquire @@ -5339,9 +5473,22 @@ Misc options timestamp Print timestamp before each test report line timediff With --timestamp, also print time passed since *previous* test started + max-connections=N Max number of open connection to server in mysqltest HERE exit(1); } +sub list_options ($) { + my $hash= shift; + + for (keys %$hash) { + s/([:=].*|[+!])$//; + s/\|/\n--/g; + print "--$_\n" unless /list-options/; + } + + exit(1); +} + diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result index 4a5b8fcf4aa..8f9b75fc664 100644 --- a/mysql-test/r/bigint.result +++ b/mysql-test/r/bigint.result @@ -404,3 +404,37 @@ describe t1; Field Type Null Key Default Extra bi decimal(19,0) NO 0 drop table t1; +# +# Bug #45360: wrong results +# +CREATE TABLE t1 (id INT AUTO_INCREMENT PRIMARY KEY, +a BIGINT(20) UNSIGNED, +b VARCHAR(20)); +INSERT INTO t1 (a) VALUES +(0), +(CAST(0x7FFFFFFFFFFFFFFF AS UNSIGNED)), +(CAST(0x8000000000000000 AS UNSIGNED)), +(CAST(0xFFFFFFFFFFFFFFFF AS UNSIGNED)); +UPDATE t1 SET b = a; +# FFFFFFFFFFFFFFFF +EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE a = 18446744073709551615 AND TRIM(a) = b; +SHOW WARNINGS; +Level Code Message +Note 1003 select 1 AS `1` from `test`.`t1` where ((`test`.`t1`.`a` = 18446744073709551615) and ('18446744073709551615' = `test`.`t1`.`b`)) +# 8000000000000000 +EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE a = 9223372036854775808 AND TRIM(a) = b; +SHOW WARNINGS; +Level Code Message +Note 1003 select 1 AS `1` from `test`.`t1` where ((`test`.`t1`.`a` = 9223372036854775808) and ('9223372036854775808' = `test`.`t1`.`b`)) +# 7FFFFFFFFFFFFFFF +EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE a = 9223372036854775807 AND TRIM(a) = b; +SHOW WARNINGS; +Level Code Message +Note 1003 select 1 AS `1` from `test`.`t1` where ((`test`.`t1`.`a` = 9223372036854775807) and ('9223372036854775807' = `test`.`t1`.`b`)) +# 0 +EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE a = 0 AND TRIM(a) = b; +SHOW WARNINGS; +Level Code Message +Note 1003 select 1 AS `1` from `test`.`t1` where ((`test`.`t1`.`a` = 0) and ('0' = `test`.`t1`.`b`)) +DROP TABLE t1; +# End of 5.1 tests diff --git a/mysql-test/r/bug39022.result b/mysql-test/r/bug39022.result index 1c02d7873e4..5963709aa2a 100644 --- a/mysql-test/r/bug39022.result +++ b/mysql-test/r/bug39022.result @@ -28,5 +28,5 @@ SELECT d FROM t2,t1 WHERE d=(SELECT MAX(a) FROM t1 WHERE t1.a > t2.d); ERROR 40001: Deadlock found when trying to get lock; try restarting transaction # in thread2 d -# in default +# in thread1; DROP TABLE t1,t2; diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index 4b96f5a5ed0..e2eebdfc992 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -5394,17 +5394,24 @@ select * from t1; ERROR HY000: File 'MYSQLD_DATADIR/test/t1.CSV' not found (Errcode: 2) unlock tables; drop table t1; -create table t1(a enum ('a') not null) engine=csv; -insert into t1 values (2); +CREATE TABLE t1 (e enum('foo','bar') NOT NULL) ENGINE = CSV; +INSERT INTO t1 VALUES(); +INSERT INTO t1 VALUES(default); +INSERT INTO t1 VALUES(0); Warnings: -Warning 1265 Data truncated for column 'a' at row 1 -select * from t1 limit 1; -ERROR HY000: Table 't1' is marked as crashed and should be repaired -repair table t1; -Table Op Msg_type Msg_text -test.t1 repair Warning Data truncated for column 'a' at row 1 -test.t1 repair status OK -select * from t1 limit 1; -a -drop table t1; +Warning 1265 Data truncated for column 'e' at row 1 +INSERT INTO t1 VALUES(3); +Warnings: +Warning 1265 Data truncated for column 'e' at row 1 +INSERT INTO t1 VALUES(-1); +Warnings: +Warning 1265 Data truncated for column 'e' at row 1 +SELECT * FROM t1; +e +foo +foo + + + +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/default.result b/mysql-test/r/default.result index 5b0d82407a2..9afffe4c3bc 100644 --- a/mysql-test/r/default.result +++ b/mysql-test/r/default.result @@ -180,7 +180,6 @@ insert into bug20691 values (2, 3, 5, '0007-01-01', 11, 13, 17, '0019-01-01 00:0 insert into bug20691 values (DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, 4); Warnings: Warning 1364 Field 'a' doesn't have a default value -Warning 1364 Field 'b' doesn't have a default value Warning 1364 Field 'c' doesn't have a default value Warning 1364 Field 'd' doesn't have a default value Warning 1364 Field 'e' doesn't have a default value @@ -193,7 +192,7 @@ a b c d e f g h i x two large 00:00:05 0007-01-01 11 13 17 0019-01-01 00:00:00 23 1 small 00:00:00 0000-00-00 0 0000-00-00 00:00:00 0 2 two large 00:00:05 0007-01-01 11 13 17 0019-01-01 00:00:00 23 3 - 00:00:00 0000-00-00 0 0000-00-00 00:00:00 0 4 + small 00:00:00 0000-00-00 0 0000-00-00 00:00:00 0 4 drop table bug20691; create table t1 (id int not null); insert into t1 values(default); diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result index 58278492985..77b2071494d 100644 --- a/mysql-test/r/delete.result +++ b/mysql-test/r/delete.result @@ -278,6 +278,18 @@ DELETE FROM t1 ORDER BY (f1(10)) LIMIT 1; ERROR 42000: Incorrect number of arguments for FUNCTION test.f1; expected 0, got 1 DROP TABLE t1; DROP FUNCTION f1; +# +# Bug #49552 : sql_buffer_result cause crash + not found records +# in multitable delete/subquery +# +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1),(2),(3); +SET SESSION SQL_BUFFER_RESULT=1; +DELETE t1 FROM (SELECT SUM(a) a FROM t1) x,t1; +SET SESSION SQL_BUFFER_RESULT=DEFAULT; +SELECT * FROM t1; +a +DROP TABLE t1; End of 5.0 tests # # Bug#46958: Assertion in Diagnostics_area::set_ok_status, trigger, @@ -337,16 +349,4 @@ END | DELETE IGNORE FROM t1; ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. DROP TABLE t1; -# -# Bug #49552 : sql_buffer_result cause crash + not found records -# in multitable delete/subquery -# -CREATE TABLE t1(a INT); -INSERT INTO t1 VALUES (1),(2),(3); -SET SESSION SQL_BUFFER_RESULT=1; -DELETE t1 FROM (SELECT SUM(a) a FROM t1) x,t1; -SET SESSION SQL_BUFFER_RESULT=DEFAULT; -SELECT * FROM t1; -a -DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result index 5a1bf1a1290..7784372de68 100644 --- a/mysql-test/r/explain.result +++ b/mysql-test/r/explain.result @@ -168,6 +168,23 @@ WHERE t1.a = d1.a; ERROR 42S22: Unknown column 'd1.a' in 'where clause' DROP TABLE t1; # +# Bug#48295: +# explain extended crash with subquery and ONLY_FULL_GROUP_BY sql_mode +# +CREATE TABLE t1 (f1 INT); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +EXPLAIN EXTENDED SELECT 1 FROM t1 +WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t ); +ERROR 42000: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause +SHOW WARNINGS; +Level Code Message +Error 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause +Note 1003 select 1 AS `1` from `test`.`t1` where <not>(<exists>(...)) +SET SESSION sql_mode=@old_sql_mode; +DROP TABLE t1; +End of 5.0 tests. +# # Bug#37870: Usage of uninitialized value caused failed assertion. # create table t1 (dt datetime not null, t time not null); @@ -195,19 +212,18 @@ dt 2001-01-01 01:01:01 drop tables t1, t2; # -# Bug#48295: -# explain extended crash with subquery and ONLY_FULL_GROUP_BY sql_mode +# Bug#47669: Query showed by EXPLAIN EXTENDED gives different result from original query # -CREATE TABLE t1 (f1 INT); -SELECT @@session.sql_mode INTO @old_sql_mode; -SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; -EXPLAIN EXTENDED SELECT 1 FROM t1 -WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t ); -ERROR 42000: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause -SHOW WARNINGS; -Level Code Message -Error 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause -Note 1003 select 1 AS `1` from `test`.`t1` where <not>(<exists>(...)) -SET SESSION sql_mode=@old_sql_mode; -DROP TABLE t1; +CREATE TABLE t1 (c int); +INSERT INTO t1 VALUES (NULL); +CREATE TABLE t2 (d int); +INSERT INTO t2 VALUES (NULL), (0); +EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) FROM t1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00 +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1276 Field or reference 'test.t1.c' of SELECT #2 was resolved in SELECT #1 +Note 1003 select (select 1 AS `1` from `test`.`t2` where (`test`.`t2`.`d` = NULL)) AS `(SELECT 1 FROM t2 WHERE d = c)` from `test`.`t1` +DROP TABLE t1, t2; End of 5.1 tests. diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 3b78851a1b9..8d1fcade88d 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -978,4 +978,21 @@ GROUP BY t1.a 1 1 DROP TABLE t1, t2; +CREATE TABLE t1 (f1 INT); +INSERT INTO t1 VALUES (),(); +EXPLAIN EXTENDED SELECT 1 FROM +(SELECT DISTINCT GROUP_CONCAT(td.f1) FROM t1,t1 AS td GROUP BY td.f1) AS d,t1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY <derived2> system NULL NULL NULL NULL 1 100.00 +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 +2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort; Distinct +2 DERIVED td ALL NULL NULL NULL NULL 2 100.00 Distinct; Using join buffer +Warnings: +Note 1003 select 1 AS `1` from (select distinct group_concat(`test`.`td`.`f1` separator ',') AS `GROUP_CONCAT(td.f1)` from `test`.`t1` join `test`.`t1` `td` group by `test`.`td`.`f1`) `d` join `test`.`t1` +SELECT 1 FROM +(SELECT DISTINCT GROUP_CONCAT(td.f1) FROM t1,t1 AS td GROUP BY td.f1) AS d,t1; +1 +1 +1 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index d144e84dfdc..8cf46e5534e 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -1307,12 +1307,12 @@ explain extended select encode(f1,'zxcv') as 'enc' from t1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found Warnings: -Note 1003 select encode('','zxcv') AS `enc` from `test`.`t1` +Note 1003 select encode(NULL,'zxcv') AS `enc` from `test`.`t1` explain extended select decode(f1,'zxcv') as 'enc' from t1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found Warnings: -Note 1003 select decode('','zxcv') AS `enc` from `test`.`t1` +Note 1003 select decode(NULL,'zxcv') AS `enc` from `test`.`t1` drop table t1; create table t1 (a bigint not null)engine=myisam; insert into t1 set a = 1024*1024*1024*4; diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result index 68c4a6a13e5..49ccb05c699 100644 --- a/mysql-test/r/gis-rtree.result +++ b/mysql-test/r/gis-rtree.result @@ -1526,4 +1526,26 @@ SELECT 1 FROM t1 WHERE a >= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1 1 DROP TABLE t1; +# +# Bug #51357: crash when using handler commands on spatial indexes +# +CREATE TABLE t1(a GEOMETRY NOT NULL,SPATIAL INDEX a(a)); +HANDLER t1 OPEN; +HANDLER t1 READ a FIRST; +a +HANDLER t1 READ a NEXT; +a +HANDLER t1 READ a PREV; +a +HANDLER t1 READ a LAST; +a +HANDLER t1 CLOSE; +HANDLER t1 OPEN; +HANDLER t1 READ a FIRST; +a +INSERT INTO t1 VALUES (GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))')); +HANDLER t1 READ a NEXT; +a +HANDLER t1 CLOSE; +DROP TABLE t1; End of 5.0 tests. diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index 9c3cc8fc89e..9568ef88786 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -12,7 +12,7 @@ explain extended select count(a) as b from t1 where a=0 having b >=0; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables Warnings: -Note 1003 select count('0') AS `b` from `test`.`t1` where 0 having (`b` >= 0) +Note 1003 select count(NULL) AS `b` from `test`.`t1` where 0 having (`b` >= 0) drop table t1; CREATE TABLE t1 ( raw_id int(10) NOT NULL default '0', @@ -430,4 +430,24 @@ SELECT b, COUNT(DISTINCT a) FROM t1 GROUP BY b HAVING b is NULL; b COUNT(DISTINCT a) NULL 1 DROP TABLE t1; +# +# Bug#50995 Having clause on subquery result produces incorrect results. +# +CREATE TABLE t1 +( +id1 INT, +id2 INT NOT NULL, +INDEX id1(id2) +); +INSERT INTO t1 SET id1=1, id2=1; +INSERT INTO t1 SET id1=2, id2=1; +INSERT INTO t1 SET id1=3, id2=1; +SELECT t1.id1, +(SELECT 0 FROM DUAL +WHERE t1.id1=t1.id1) AS amount FROM t1 +WHERE t1.id2 = 1 +HAVING amount > 0 +ORDER BY t1.id1; +id1 amount +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/r/innodb-autoinc.result b/mysql-test/r/innodb-autoinc.result index c03daa3565e..a36b3a1a865 100644 --- a/mysql-test/r/innodb-autoinc.result +++ b/mysql-test/r/innodb-autoinc.result @@ -1161,3 +1161,86 @@ t1 CREATE TABLE `t1` ( PRIMARY KEY (`c1`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 DROP TABLE t1; +DROP TABLE IF EXISTS t1; +Warnings: +Note 1051 Unknown table 't1' +CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (-685113344), (1), (NULL), (NULL); +SELECT * FROM t1; +c1 +-685113344 +1 +2 +3 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (-685113344), (2), (NULL), (NULL); +SELECT * FROM t1; +c1 +-685113344 +2 +3 +4 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL), (2), (-685113344), (NULL); +INSERT INTO t1 VALUES (4), (5), (6), (NULL); +SELECT * FROM t1; +c1 +-685113344 +1 +2 +3 +4 +5 +6 +7 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL), (2), (-685113344), (5); +SELECT * FROM t1; +c1 +-685113344 +1 +2 +5 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1), (2), (-685113344), (NULL); +SELECT * FROM t1; +c1 +-685113344 +1 +2 +3 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index b54fb90b412..586cd5477a7 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -2281,4 +2281,40 @@ CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb ; SELECT 1 FROM t1 JOIN t1 a USING(a) GROUP BY t1.a,t1.a; 1 DROP TABLE t1; +# +# Bug#50843: Filesort used instead of clustered index led to +# performance degradation. +# +create table t1(f1 int not null primary key, f2 int) engine=innodb; +create table t2(f1 int not null, key (f1)) engine=innodb; +insert into t1 values (1,1),(2,2),(3,3); +insert into t2 values (1),(2),(3); +explain select t1.* from t1 left join t2 using(f1) group by t1.f1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 4 NULL 3 +1 SIMPLE t2 ref f1 f1 4 test.t1.f1 1 Using index +drop table t1,t2; +# +# +# Bug #39653: find_shortest_key in sql_select.cc does not consider +# clustered primary keys +# +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c INT, d INT, e INT, f INT, +KEY (b,c)) ENGINE=INNODB; +INSERT INTO t1 VALUES (1,1,1,1,1,1), (2,2,2,2,2,2), (3,3,3,3,3,3), +(4,4,4,4,4,4), (5,5,5,5,5,5), (6,6,6,6,6,6), +(7,7,7,7,7,7), (8,8,8,8,8,8), (9,9,9,9,9,9), +(11,11,11,11,11,11); +EXPLAIN SELECT COUNT(*) FROM t1; +id 1 +select_type SIMPLE +table t1 +type index +possible_keys NULL +key b +key_len 10 +ref NULL +rows 10 +Extra Using index +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index 8691eb27220..102b39c3992 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -1145,3 +1145,14 @@ NULL NULL 1 DROP TABLE t1, t2, mm1; +# +# Bug #50335: Assertion `!(order->used & map)' in eq_ref_table +# +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)); +INSERT INTO t1 VALUES (0,0), (1,1); +SELECT * FROM t1 STRAIGHT_JOIN t1 t2 ON t1.a=t2.a AND t1.a=t2.b ORDER BY t2.a, t1.a; +a b a b +0 0 0 0 +1 1 1 1 +DROP TABLE t1; +End of 5.1 tests diff --git a/mysql-test/r/log_tables_upgrade.result b/mysql-test/r/log_tables_upgrade.result new file mode 100644 index 00000000000..5d9be85a48a --- /dev/null +++ b/mysql-test/r/log_tables_upgrade.result @@ -0,0 +1,47 @@ +# +# Bug#49823: mysql_upgrade fatal error due to general_log / slow_low CSV NULL +# +USE test; +SET @saved_general_log = @@GLOBAL.general_log; +SET GLOBAL general_log = OFF; +USE mysql; +FLUSH TABLES; +REPAIR TABLE test.bug49823; +Table Op Msg_type Msg_text +test.bug49823 repair status OK +RENAME TABLE general_log TO renamed_general_log; +RENAME TABLE test.bug49823 TO general_log; +mtr.global_suppressions OK +mtr.test_suppressions OK +mysql.columns_priv OK +mysql.db OK +mysql.event OK +mysql.func OK +mysql.general_log +Error : You can't use locks with log tables. +status : OK +mysql.help_category OK +mysql.help_keyword OK +mysql.help_relation OK +mysql.help_topic OK +mysql.host OK +mysql.ndb_binlog_index OK +mysql.plugin OK +mysql.proc OK +mysql.procs_priv OK +mysql.renamed_general_log OK +mysql.servers OK +mysql.slow_log +Error : You can't use locks with log tables. +status : OK +mysql.tables_priv OK +mysql.time_zone OK +mysql.time_zone_leap_second OK +mysql.time_zone_name OK +mysql.time_zone_transition OK +mysql.time_zone_transition_type OK +mysql.user OK +DROP TABLE general_log; +RENAME TABLE renamed_general_log TO general_log; +SET GLOBAL general_log = @saved_general_log; +USE test; diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 82655dd46ec..b08435cb1a7 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -2339,4 +2339,21 @@ CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; +# +# Bug#51304: checksum table gives different results +# for same data when using bit fields +# +CREATE TABLE t1(a INT, b BIT(1)); +INSERT INTO t1 VALUES(1, 0), (2, 1); +CREATE TABLE t2 SELECT * FROM t1; +CHECKSUM TABLE t1 EXTENDED; +Table Checksum +test.t1 3775188275 +CHECKSUM TABLE t2 EXTENDED; +Table Checksum +test.t2 3775188275 +CHECKSUM TABLE t3 EXTENDED; +Table Checksum +test.t3 3775188275 +DROP TABLE t1, t2, t3; End of 5.1 tests diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 2e3a9489593..67c08b0ae97 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -147,9 +147,10 @@ hello hello ;;;;;;;; # MySQL: -- The -mysqltest: At line 1: End of line junk detected: "6" -mysqltest: At line 1: End of line junk detected: "6" -mysqltest: At line 1: Missing delimiter +mysqltest: At line 1: Extra argument '6' passed to 'sleep' +mysqltest: At line 1: Extra argument '6' passed to 'sleep' +mysqltest: At line 1: Extra argument 'A comment +show status' passed to 'sleep' mysqltest: At line 1: End of line junk detected: "sleep 7 # Another comment " @@ -216,6 +217,12 @@ source database echo message echo message mysqltest: At line 1: Missing argument in exec +1 +1 +2 +2 +X +3 MySQL "MySQL" MySQL: The @@ -348,8 +355,10 @@ here is the sourced script here is the sourced script "hello" "hello" -mysqltest: At line 1: Missing argument to sleep -mysqltest: At line 1: Missing argument to real_sleep +mysqltest: At line 2: Invalid argument to sleep "xyz" +mysqltest: At line 2: Invalid argument to real_sleep "xyz" +mysqltest: At line 1: Missing required argument 'sleep_delay' to command 'sleep' +mysqltest: At line 1: Missing required argument 'sleep_delay' to command 'real_sleep' mysqltest: At line 1: Invalid argument to sleep "abc" mysqltest: At line 1: Invalid argument to real_sleep "abc" 1 @@ -377,6 +386,10 @@ test test2 test3 test4 +outer +true-inner +true-inner again +true-outer Counter is greater than 0, (counter=10) Counter is not 0, (counter=0) 1 @@ -417,6 +430,9 @@ mysqltest: At line 1: Wrong number of arguments to replace_column in 'replace_co mysqltest: At line 1: Wrong column number to replace_column in 'replace_column a b' mysqltest: At line 1: Wrong column number to replace_column in 'replace_column a 1' mysqltest: At line 1: Wrong column number to replace_column in 'replace_column 1 b c ' +select "LONG_STRING" as x; +x +LONG_STRING mysqltest: At line 1: Invalid integer argument "10!" mysqltest: At line 1: Invalid integer argument "a" mysqltest: At line 1: Missing required argument 'connection name' to command 'connect' @@ -523,7 +539,28 @@ a D 1 1 1 4 drop table t1; +create table t1 ( f1 char(10)); +insert into t1 values ("Abcd"); +select * from t1; +f1 +Abcd +select * from t2;; +ERROR 42S02: Table 'test.t2' doesn't exist +select * from t1; +f1 +Abcd +select * from t1;; +Result coming up +f1 +Abcd +select * from t1;; +f1 +Abcd +mysqltest: At line 2: Cannot run query on connection between send and reap +select * from t1;; +drop table t1; mysqltest: At line 1: Missing required argument 'filename' to command 'remove_file' +mysqltest: At line 1: Missing required argument 'directory' to command 'remove_files_wildcard' mysqltest: At line 1: Missing required argument 'filename' to command 'write_file' mysqltest: At line 1: End of file encountered before 'EOF' delimiter was found Content for test_file1 @@ -553,6 +590,8 @@ hello mysqltest: At line 1: Max delimiter length(16) exceeded hello hello +val is 5 +val is 5 mysqltest: At line 1: test of die Some output create table t1( a int, b char(255), c timestamp); @@ -680,6 +719,29 @@ INSERT INTO t1 SELECT f1 - 256 FROM t1; INSERT INTO t1 SELECT f1 - 512 FROM t1; SELECT * FROM t1; DROP TABLE t1; +select "500g blåbærsyltetøy" as "will be lower cased"; +will be lower cased +500g blåbærsyltetøy +SELECT "UPPER" AS "WILL NOT BE lower cased"; +WILL NOT BE lower cased +UPPER +UP +SELECT 0 as "UP AGAIN"; +UP AGAIN +0 +select "abcdef" as "uvwxyz"; +uvwxyz +abcdef +select "xyz" as name union select "abc" as name order by name desc; +name +abc +xyz +select 1 as "some new text"; +some new text +1 +select 0 as "will not lower case ÄËÐ"; +will not lower case ÄËÐ +0 CREATE TABLE t1( a int, b varchar(255), c datetime ); @@ -726,6 +788,8 @@ mysqltest: At line 1: change user failed: Access denied for user 'root'@'localho file1.txt file1.txt file2.txt +file11.txt +dir-list.txt SELECT 'c:\\a.txt' AS col; col z diff --git a/mysql-test/r/partition_debug_sync.result b/mysql-test/r/partition_debug_sync.result new file mode 100644 index 00000000000..5eb19f42395 --- /dev/null +++ b/mysql-test/r/partition_debug_sync.result @@ -0,0 +1,57 @@ +DROP TABLE IF EXISTS t1, t2; +SET DEBUG_SYNC= 'RESET'; +# +# Bug#42438: Crash ha_partition::change_table_ptr +# Test when remove partitioning is done while drop table is waiting +# for the table. +# Con 1 +SET DEBUG_SYNC= 'RESET'; +CREATE TABLE t1 +(a INTEGER, +b INTEGER NOT NULL, +KEY (b)) +ENGINE = MYISAM +/*!50100 PARTITION BY RANGE (a) +(PARTITION p0 VALUES LESS THAN (2), +PARTITION p1 VALUES LESS THAN (20), +PARTITION p2 VALUES LESS THAN (100), +PARTITION p3 VALUES LESS THAN MAXVALUE ) */; +SET DEBUG_SYNC= 'alter_table_before_create_table_no_lock SIGNAL removing_partitioning WAIT_FOR waiting_for_alter'; +SET DEBUG_SYNC= 'alter_table_before_main_binlog SIGNAL partitioning_removed'; +ALTER TABLE t1 REMOVE PARTITIONING; +# Con default +SET DEBUG_SYNC= 'now WAIT_FOR removing_partitioning'; +SET DEBUG_SYNC= 'waiting_for_table SIGNAL waiting_for_alter'; +SET DEBUG_SYNC= 'rm_table_part2_before_delete_table WAIT_FOR partitioning_removed'; +DROP TABLE IF EXISTS t1; +# Con 1 +SET DEBUG_SYNC= 'RESET'; +SET DEBUG_SYNC= 'RESET'; +# +# Bug#42438: Crash ha_partition::change_table_ptr +# Test when remove partitioning is failing due to drop table is already +# in progress. +CREATE TABLE t2 +(a INTEGER, +b INTEGER NOT NULL, +KEY (b)) +ENGINE = MYISAM +/*!50100 PARTITION BY RANGE (a) +(PARTITION p0 VALUES LESS THAN (2), +PARTITION p1 VALUES LESS THAN (20), +PARTITION p2 VALUES LESS THAN (100), +PARTITION p3 VALUES LESS THAN MAXVALUE ) */; +SET DEBUG_SYNC= 'before_lock_tables_takes_lock SIGNAL removing_partitions WAIT_FOR waiting_for_alter'; +SET DEBUG_SYNC= 'alter_table_before_rename_result_table WAIT_FOR delete_done'; +ALTER TABLE t2 REMOVE PARTITIONING; +# Con default +SET DEBUG_SYNC= 'now WAIT_FOR removing_partitions'; +SET DEBUG_SYNC= 'waiting_for_table SIGNAL waiting_for_alter'; +SET DEBUG_SYNC= 'rm_table_part2_before_binlog SIGNAL delete_done'; +DROP TABLE IF EXISTS t2; +# Con 1 +ERROR 42S02: Table 'test.t2' doesn't exist +SET DEBUG_SYNC= 'RESET'; +# Con default +SET DEBUG_SYNC= 'RESET'; +End of 5.1 tests diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index bd7968583dc..fb4175ed5ca 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4050,10 +4050,10 @@ join_0.c1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables Warnings: -Note 1003 select '0' AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by '0','0','0','0','0' +Note 1003 select NULL AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by NULL,NULL,NULL,NULL,NULL SHOW WARNINGS; Level Code Message -Note 1003 select '0' AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by '0','0','0','0','0' +Note 1003 select NULL AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by NULL,NULL,NULL,NULL,NULL DROP TABLE t1; SELECT 1 AS ` `; @@ -4648,17 +4648,17 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND b=b AND c=c) OR b > 20; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found Warnings: -Note 1003 select '0' AS `a`,'0' AS `b`,'0' AS `c` from `test`.`t1` where 1 +Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1 EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND a=a AND b=b) OR b > 20; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found Warnings: -Note 1003 select '0' AS `a`,'0' AS `b`,'0' AS `c` from `test`.`t1` where 1 +Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1 EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a=a AND b=b AND a=a) OR b > 20; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found Warnings: -Note 1003 select '0' AS `a`,'0' AS `b`,'0' AS `c` from `test`.`t1` where 1 +Note 1003 select NULL AS `a`,NULL AS `b`,NULL AS `c` from `test`.`t1` where 1 DROP TABLE t1; # # Bug#45266: Uninitialized variable lead to an empty result. diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 2dc26bfb048..bda33109524 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1496,7 +1496,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` < (select max('0') from `test`.`t2`))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` < (select max(NULL) from `test`.`t2`))) select * from t3 where a >= some (select b from t2); a explain extended select * from t3 where a >= some (select b from t2); @@ -1504,7 +1504,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= (select min('0') from `test`.`t2`))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= (select min(NULL) from `test`.`t2`))) select * from t3 where a >= all (select b from t2 group by 1); a 6 @@ -1515,7 +1515,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` < <max>(select '0' AS `b` from `test`.`t2` group by 1))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>((`test`.`t3`.`a` < <max>(select NULL AS `b` from `test`.`t2` group by 1))) select * from t3 where a >= some (select b from t2 group by 1); a explain extended select * from t3 where a >= some (select b from t2 group by 1); @@ -1523,7 +1523,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found Warnings: -Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= <min>(select '0' AS `b` from `test`.`t2` group by 1))) +Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>((`test`.`t3`.`a` >= <min>(select NULL AS `b` from `test`.`t2` group by 1))) select * from t3 where NULL >= any (select b from t2); a explain extended select * from t3 where NULL >= any (select b from t2); diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index 51feab0a421..9f32a10a3fb 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -785,4 +785,19 @@ t1 CREATE TABLE `t1` ( KEY `a` (`a`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +# +# Bug#50591 bit(31) causes Duplicate entry '1-NULL' for key 'group_key' +# +CREATE TABLE t1(a INT, b BIT(7) NOT NULL); +INSERT INTO t1 VALUES (NULL, 0),(NULL, 0); +SELECT SUM(a) FROM t1 GROUP BY b, a; +SUM(a) +NULL +DROP TABLE t1; +CREATE TABLE t1(a INT, b BIT(7) NOT NULL, c BIT(8) NOT NULL); +INSERT INTO t1 VALUES (NULL, 0, 0),(NULL, 0, 0); +SELECT SUM(a) FROM t1 GROUP BY c, b, a; +SUM(a) +NULL +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 43d7cade227..98d177a5448 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1585,7 +1585,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 2 UNION t1 system NULL NULL NULL NULL 0 0.00 const row not found NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort Warnings: -Note 1003 select '0' AS `a` from `test`.`t1` union select '0' AS `a` from `test`.`t1` order by `a` +Note 1003 select NULL AS `a` from `test`.`t1` union select NULL AS `a` from `test`.`t1` order by `a` DROP TABLE t1; End of 5.0 tests # diff --git a/mysql-test/r/variables+c.result b/mysql-test/r/variables_community.result index 7a2976d1267..7a2976d1267 100644 --- a/mysql-test/r/variables+c.result +++ b/mysql-test/r/variables_community.result diff --git a/mysql-test/std_data/bug49823.CSM b/mysql-test/std_data/bug49823.CSM Binary files differnew file mode 100644 index 00000000000..ee345049d99 --- /dev/null +++ b/mysql-test/std_data/bug49823.CSM diff --git a/mysql-test/std_data/bug49823.CSV b/mysql-test/std_data/bug49823.CSV new file mode 100644 index 00000000000..ffc319e2446 --- /dev/null +++ b/mysql-test/std_data/bug49823.CSV @@ -0,0 +1 @@ +"2010-02-26 13:32:26","root[root] @ localhost []",2,1,"Query","SELECT 1" diff --git a/mysql-test/std_data/bug49823.frm b/mysql-test/std_data/bug49823.frm Binary files differnew file mode 100644 index 00000000000..527807da1c9 --- /dev/null +++ b/mysql-test/std_data/bug49823.frm diff --git a/mysql-test/suite/federated/federated.result b/mysql-test/suite/federated/federated.result index 57f665995a1..db4ffc38213 100644 --- a/mysql-test/suite/federated/federated.result +++ b/mysql-test/suite/federated/federated.result @@ -2153,6 +2153,29 @@ DROP TABLE t1; End of 5.0 tests create server 's1' foreign data wrapper 'mysql' options (port 3306); drop server 's1'; +# +# Bug #32426: FEDERATED query returns corrupt results for ORDER BY on a TEXT +# +CREATE TABLE federated.t1(a TEXT); +INSERT INTO federated.t1 VALUES('abc'), ('gh'), ('f'), ('ijk'), ('de'); +CREATE TABLE federated.t1(a TEXT) ENGINE=FEDERATED +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +SELECT * FROM federated.t1 ORDER BY A; +a +abc +de +f +gh +ijk +SELECT * FROM federated.t1 ORDER BY A DESC; +a +ijk +gh +f +de +abc +DROP TABLE federated.t1; +DROP TABLE federated.t1; End of 5.1 tests SET @@GLOBAL.CONCURRENT_INSERT= @OLD_MASTER_CONCURRENT_INSERT; SET @@GLOBAL.CONCURRENT_INSERT= @OLD_SLAVE_CONCURRENT_INSERT; diff --git a/mysql-test/suite/federated/federated.test b/mysql-test/suite/federated/federated.test index 870bbcb8f71..a1d86462c11 100644 --- a/mysql-test/suite/federated/federated.test +++ b/mysql-test/suite/federated/federated.test @@ -1971,6 +1971,28 @@ connection default; create server 's1' foreign data wrapper 'mysql' options (port 3306); drop server 's1'; + +--echo # +--echo # Bug #32426: FEDERATED query returns corrupt results for ORDER BY on a TEXT +--echo # +connection slave; +CREATE TABLE federated.t1(a TEXT); +INSERT INTO federated.t1 VALUES('abc'), ('gh'), ('f'), ('ijk'), ('de'); + +connection master; +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE federated.t1(a TEXT) ENGINE=FEDERATED + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; +SELECT * FROM federated.t1 ORDER BY A; +SELECT * FROM federated.t1 ORDER BY A DESC; +DROP TABLE federated.t1; + +connection slave; +DROP TABLE federated.t1; + +connection default; + + --echo End of 5.1 tests SET @@GLOBAL.CONCURRENT_INSERT= @OLD_MASTER_CONCURRENT_INSERT; connection slave; diff --git a/mysql-test/suite/rpl/r/rpl_row_create_table.result b/mysql-test/suite/rpl/r/rpl_row_create_table.result index 4c2b9ebeaee..8a1b7a805aa 100644 --- a/mysql-test/suite/rpl/r/rpl_row_create_table.result +++ b/mysql-test/suite/rpl/r/rpl_row_create_table.result @@ -241,10 +241,12 @@ STOP SLAVE; SET GLOBAL storage_engine=@storage_engine; START SLAVE; ================ BUG#22864 ================ -STOP SLAVE; -RESET SLAVE; -RESET MASTER; -START SLAVE; +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; SET AUTOCOMMIT=0; CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(2),(3); @@ -264,15 +266,6 @@ t1 t2 t3 t4 -SELECT TABLE_NAME,ENGINE -FROM INFORMATION_SCHEMA.TABLES -WHERE TABLE_NAME LIKE 't_' -ORDER BY TABLE_NAME; -TABLE_NAME ENGINE -t1 MyISAM -t2 InnoDB -t3 InnoDB -t4 InnoDB SELECT * FROM t1 ORDER BY a; a 1 @@ -334,15 +327,6 @@ t1 t2 t3 t4 -SELECT TABLE_NAME,ENGINE -FROM INFORMATION_SCHEMA.TABLES -WHERE TABLE_NAME LIKE 't_' -ORDER BY TABLE_NAME; -TABLE_NAME ENGINE -t1 MyISAM -t2 InnoDB -t3 InnoDB -t4 InnoDB SELECT * FROM t1 ORDER BY a; a 1 diff --git a/mysql-test/suite/rpl/r/rpl_show_slave_running.result b/mysql-test/suite/rpl/r/rpl_show_slave_running.result new file mode 100644 index 00000000000..da26190e76d --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_show_slave_running.result @@ -0,0 +1,42 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +include/stop_slave.inc +SELECT GET_LOCK("debug_lock.before_get_running_status_yes", 1000); +GET_LOCK("debug_lock.before_get_running_status_yes", 1000) +1 +set global debug= 'd,debug_lock.before_get_running_status_yes'; +Slave_running, Slave_IO_Running, Slave_SQL_Running, must be OFF, NO, NO in three following queries +SHOW STATUS LIKE 'Slave_running'; +Variable_name Value +Slave_running OFF +Slave_IO_Running= No +Slave_SQL_Running= No +start slave io_thread; +Slave_running, Slave_IO_Running, Slave_SQL_Running must be OFF NO NO in three following queries +SHOW STATUS LIKE 'Slave_running'; +Variable_name Value +Slave_running OFF +Slave_IO_Running= No +Slave_SQL_Running= No +SELECT RELEASE_LOCK("debug_lock.before_get_running_status_yes"); +RELEASE_LOCK("debug_lock.before_get_running_status_yes") +1 +Slave_running, Slave_IO_Running, Slave_SQL_Running must be OFF YES NO in three following queries +SHOW STATUS LIKE 'Slave_running'; +Variable_name Value +Slave_running OFF +Slave_IO_Running= Yes +Slave_SQL_Running= No +start slave sql_thread; +Slave_running, Slave_IO_Running, Slave_SQL_Running must be ON, YES, YES in three following queries +SHOW STATUS LIKE 'Slave_running'; +Variable_name Value +Slave_running ON +Slave_IO_Running= Yes +Slave_SQL_Running= Yes +set global debug= ''; +End of tests diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index d2cb1ce9518..ef77c54e067 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -10,4 +10,4 @@ # ############################################################################## -rpl_row_create_table : Bug#45576 2009-12-01 joro rpl_row_create_table fails on PB2 +rpl_row_create_table : Bug#51574 Feb 27 2010 andrei failed different way than earlier with bug#45576 diff --git a/mysql-test/suite/rpl/t/rpl_row_create_table.test b/mysql-test/suite/rpl/t/rpl_row_create_table.test index 54dcbd24419..e30982da605 100644 --- a/mysql-test/suite/rpl/t/rpl_row_create_table.test +++ b/mysql-test/suite/rpl/t/rpl_row_create_table.test @@ -136,13 +136,9 @@ START SLAVE; # BUG#22864 (Rollback following CREATE ... SELECT discards 'CREATE # table' from log): --echo ================ BUG#22864 ================ -connection slave; -STOP SLAVE; -RESET SLAVE; -connection master; -RESET MASTER; -connection slave; -START SLAVE; + +--source include/master-slave-reset.inc + connection master; SET AUTOCOMMIT=0; CREATE TABLE t1 (a INT); @@ -160,10 +156,6 @@ INSERT INTO t1 VALUES (4),(5),(6); ROLLBACK; SHOW TABLES; -SELECT TABLE_NAME,ENGINE - FROM INFORMATION_SCHEMA.TABLES - WHERE TABLE_NAME LIKE 't_' -ORDER BY TABLE_NAME; SELECT * FROM t1 ORDER BY a; SELECT * FROM t2 ORDER BY a; SELECT * FROM t3 ORDER BY a; @@ -173,10 +165,6 @@ SELECT * FROM t4 ORDER BY a; SHOW BINLOG EVENTS FROM 106; sync_slave_with_master; SHOW TABLES; -SELECT TABLE_NAME,ENGINE - FROM INFORMATION_SCHEMA.TABLES - WHERE TABLE_NAME LIKE 't_' -ORDER BY TABLE_NAME; SELECT * FROM t1 ORDER BY a; SELECT * FROM t2 ORDER BY a; SELECT * FROM t3 ORDER BY a; diff --git a/mysql-test/suite/rpl/t/rpl_show_slave_running.test b/mysql-test/suite/rpl/t/rpl_show_slave_running.test new file mode 100644 index 00000000000..62cc311e6b2 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_show_slave_running.test @@ -0,0 +1,76 @@ +# +# Bug #30703 SHOW STATUS LIKE 'Slave_running' is not compatible with `SHOW SLAVE STATUS' +# The test verifies that SHOW STATUS LIKE 'Slave_running' displays ON +# if and only if `SHOW SLAVE STATUS' displays YES for Slave_IO_Running and Slave_SQL_Running +# +source include/master-slave.inc; +source include/have_debug.inc; + +connection slave; + +source include/stop_slave.inc; +let $debug_saved= `select @@global.debug`; +let $debug_lock= "debug_lock.before_get_running_status_yes"; +eval SELECT GET_LOCK($debug_lock, 1000); +set global debug= 'd,debug_lock.before_get_running_status_yes'; + +# Test 1. Slave is stopped + +--echo Slave_running, Slave_IO_Running, Slave_SQL_Running, must be OFF, NO, NO in three following queries + +SHOW STATUS LIKE 'Slave_running'; +let $status= query_get_value("show slave status", Slave_IO_Running, 1); +echo Slave_IO_Running= $status; +let $status= query_get_value("show slave status", Slave_SQL_Running, 1); +echo Slave_SQL_Running= $status; + +# Test 2. The slave IO thread is started but not yet got connected to master +# and SQL thread is not started + +start slave io_thread; + +--echo Slave_running, Slave_IO_Running, Slave_SQL_Running must be OFF NO NO in three following queries + +SHOW STATUS LIKE 'Slave_running'; +let $status= query_get_value("show slave status", Slave_IO_Running, 1); +echo Slave_IO_Running= $status; +let $status= query_get_value("show slave status", Slave_SQL_Running, 1); +echo Slave_SQL_Running= $status; + +# Test 3. The slave IO thread is started and got connected to master +# and SQL thread is still not started + +eval SELECT RELEASE_LOCK($debug_lock); +let $slave_param= Slave_IO_Running; +let $slave_param_value= YES; +source include/wait_for_slave_param.inc; + +--echo Slave_running, Slave_IO_Running, Slave_SQL_Running must be OFF YES NO in three following queries + +SHOW STATUS LIKE 'Slave_running'; +let $status= query_get_value("show slave status", Slave_IO_Running, 1); +echo Slave_IO_Running= $status; +let $status= query_get_value("show slave status", Slave_SQL_Running, 1); +echo Slave_SQL_Running= $status; + +# Test 4. The slave IO thread is started and got connected to master +# and SQL thread is started + +start slave sql_thread; +source include/wait_for_slave_sql_to_start.inc; + +--echo Slave_running, Slave_IO_Running, Slave_SQL_Running must be ON, YES, YES in three following queries + +SHOW STATUS LIKE 'Slave_running'; +let $status= query_get_value("show slave status", Slave_IO_Running, 1); +echo Slave_IO_Running= $status; +let $status= query_get_value("show slave status", Slave_SQL_Running, 1); +echo Slave_SQL_Running= $status; + +# cleanup + +connection slave; + +eval set global debug= '$debug_saved'; + +--echo End of tests diff --git a/mysql-test/suite/rpl/t/rpl_slave_skip.test b/mysql-test/suite/rpl/t/rpl_slave_skip.test index f4cb0f69e93..c5ee6793277 100644 --- a/mysql-test/suite/rpl/t/rpl_slave_skip.test +++ b/mysql-test/suite/rpl/t/rpl_slave_skip.test @@ -27,7 +27,7 @@ connection slave; # Stop when reaching the the first table map event. START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=762; -wait_for_slave_to_stop; +source include/wait_for_slave_sql_to_stop.inc; --replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 8 # 9 # 23 # 33 # 35 # 36 # query_vertical SHOW SLAVE STATUS; @@ -59,7 +59,7 @@ source include/show_binlog_events.inc; connection slave; START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=106; -wait_for_slave_to_stop; +source include/wait_for_slave_sql_to_stop.inc; SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE; sync_with_master; diff --git a/mysql-test/suite/sys_vars/r/log_basic.result b/mysql-test/suite/sys_vars/r/log_basic.result index 18a12b72437..e7696d4f115 100644 --- a/mysql-test/suite/sys_vars/r/log_basic.result +++ b/mysql-test/suite/sys_vars/r/log_basic.result @@ -18,4 +18,4 @@ VARIABLE_VALUE OFF SET @@global.log= @start_log; Warnings: -Warning 1287 The syntax '@@log' is deprecated and will be removed in MySQL 7.0. Please use '@@general_log' instead +Warning 1287 '@@log' is deprecated and will be removed in a future release. Please use '@@general_log' instead diff --git a/mysql-test/suite/sys_vars/r/log_bin_trust_routine_creators_basic.result b/mysql-test/suite/sys_vars/r/log_bin_trust_routine_creators_basic.result index 66e253645b1..3360d4384ff 100644 --- a/mysql-test/suite/sys_vars/r/log_bin_trust_routine_creators_basic.result +++ b/mysql-test/suite/sys_vars/r/log_bin_trust_routine_creators_basic.result @@ -5,17 +5,17 @@ SELECT @start_global_value; '#--------------------FN_DYNVARS_064_01-------------------------#' SET @@global.log_bin_trust_routine_creators = TRUE; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 '@@log_bin_trust_routine_creators' is deprecated and will be removed in a future release. Please use '@@log_bin_trust_function_creators' instead SET @@global.log_bin_trust_routine_creators = DEFAULT; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 '@@log_bin_trust_routine_creators' is deprecated and will be removed in a future release. Please use '@@log_bin_trust_function_creators' instead SELECT @@global.log_bin_trust_routine_creators; @@global.log_bin_trust_routine_creators 0 '#--------------------FN_DYNVARS_064_02-------------------------#' SET @@global.log_bin_trust_routine_creators = DEFAULT; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 '@@log_bin_trust_routine_creators' is deprecated and will be removed in a future release. Please use '@@log_bin_trust_function_creators' instead SELECT @@global.log_bin_trust_routine_creators = 'FALSE'; @@global.log_bin_trust_routine_creators = 'FALSE' 1 @@ -24,37 +24,37 @@ Warning 1292 Truncated incorrect DOUBLE value: 'FALSE' '#--------------------FN_DYNVARS_064_03-------------------------#' SET @@global.log_bin_trust_routine_creators = ON; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 '@@log_bin_trust_routine_creators' is deprecated and will be removed in a future release. Please use '@@log_bin_trust_function_creators' instead SELECT @@global.log_bin_trust_routine_creators; @@global.log_bin_trust_routine_creators 1 SET @@global.log_bin_trust_routine_creators = OFF; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 '@@log_bin_trust_routine_creators' is deprecated and will be removed in a future release. Please use '@@log_bin_trust_function_creators' instead SELECT @@global.log_bin_trust_routine_creators; @@global.log_bin_trust_routine_creators 0 SET @@global.log_bin_trust_routine_creators = 0; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 '@@log_bin_trust_routine_creators' is deprecated and will be removed in a future release. Please use '@@log_bin_trust_function_creators' instead SELECT @@global.log_bin_trust_routine_creators; @@global.log_bin_trust_routine_creators 0 SET @@global.log_bin_trust_routine_creators = 1; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 '@@log_bin_trust_routine_creators' is deprecated and will be removed in a future release. Please use '@@log_bin_trust_function_creators' instead SELECT @@global.log_bin_trust_routine_creators; @@global.log_bin_trust_routine_creators 1 SET @@global.log_bin_trust_routine_creators = TRUE; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 '@@log_bin_trust_routine_creators' is deprecated and will be removed in a future release. Please use '@@log_bin_trust_function_creators' instead SELECT @@global.log_bin_trust_routine_creators; @@global.log_bin_trust_routine_creators 1 SET @@global.log_bin_trust_routine_creators = FALSE; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 '@@log_bin_trust_routine_creators' is deprecated and will be removed in a future release. Please use '@@log_bin_trust_function_creators' instead SELECT @@global.log_bin_trust_routine_creators; @@global.log_bin_trust_routine_creators 0 @@ -70,7 +70,7 @@ SET @@global.log_bin_trust_routine_creators = "OFFF"; ERROR 42000: Variable 'log_bin_trust_routine_creators' can't be set to the value of 'OFFF' SET @@global.log_bin_trust_routine_creators = OF; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 '@@log_bin_trust_routine_creators' is deprecated and will be removed in a future release. Please use '@@log_bin_trust_function_creators' instead SELECT @@global.log_bin_trust_routine_creators; @@global.log_bin_trust_routine_creators 0 @@ -96,14 +96,14 @@ ERROR HY000: Variable 'log_bin_trust_routine_creators' is a GLOBAL variable '#---------------------FN_DYNVARS_064_07----------------------#' SET @@global.log_bin_trust_routine_creators = TRUE; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 '@@log_bin_trust_routine_creators' is deprecated and will be removed in a future release. Please use '@@log_bin_trust_function_creators' instead SELECT @@log_bin_trust_routine_creators = @@global.log_bin_trust_routine_creators; @@log_bin_trust_routine_creators = @@global.log_bin_trust_routine_creators 1 '#---------------------FN_DYNVARS_064_08----------------------#' SET @@global.log_bin_trust_routine_creators = TRUE; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 '@@log_bin_trust_routine_creators' is deprecated and will be removed in a future release. Please use '@@log_bin_trust_function_creators' instead SELECT @@log_bin_trust_routine_creators; @@log_bin_trust_routine_creators 1 @@ -115,7 +115,7 @@ SELECT log_bin_trust_routine_creators = @@session.log_bin_trust_routine_creators ERROR 42S22: Unknown column 'log_bin_trust_routine_creators' in 'field list' SET @@global.log_bin_trust_routine_creators = @start_global_value; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 '@@log_bin_trust_routine_creators' is deprecated and will be removed in a future release. Please use '@@log_bin_trust_function_creators' instead SELECT @@global.log_bin_trust_routine_creators; @@global.log_bin_trust_routine_creators 1 diff --git a/mysql-test/suite/sys_vars/t/innodb_table_locks_func.test b/mysql-test/suite/sys_vars/t/innodb_table_locks_func.test index 6638a20c926..330addd6b3b 100644 --- a/mysql-test/suite/sys_vars/t/innodb_table_locks_func.test +++ b/mysql-test/suite/sys_vars/t/innodb_table_locks_func.test @@ -78,6 +78,7 @@ COMMIT; --echo 'CONNECTION con2' CONNECTION con2; +reap; UNLOCK tables; DROP TABLE t1; diff --git a/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test b/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test index 2ef6e34b0b3..5e0314c25ae 100644 --- a/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test +++ b/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test @@ -127,6 +127,7 @@ connection con0; SET SESSION low_priority_updates = OFF; --echo ** Connection con1 ** connection con1; +reap; SET SESSION low_priority_updates = OFF; --echo ** Connection default** connection default; diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test index 5a589816dcd..e19bba971f9 100644 --- a/mysql-test/t/bigint.test +++ b/mysql-test/t/bigint.test @@ -327,3 +327,38 @@ drop table t1; create table t1 select -9223372036854775809 bi; describe t1; drop table t1; + +--echo # +--echo # Bug #45360: wrong results +--echo # + +CREATE TABLE t1 (id INT AUTO_INCREMENT PRIMARY KEY, + a BIGINT(20) UNSIGNED, + b VARCHAR(20)); + +INSERT INTO t1 (a) VALUES + (0), + (CAST(0x7FFFFFFFFFFFFFFF AS UNSIGNED)), + (CAST(0x8000000000000000 AS UNSIGNED)), + (CAST(0xFFFFFFFFFFFFFFFF AS UNSIGNED)); + +UPDATE t1 SET b = a; + +let $n = `SELECT MAX(id) FROM t1`; +while($n) { + let $x = `SELECT a FROM t1 WHERE id = $n`; + dec $n; + let $hex = `SELECT HEX($x)`; + echo # $hex; + + --disable_result_log + eval EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE a = $x AND TRIM(a) = b; + --enable_result_log + SHOW WARNINGS; +} + +DROP TABLE t1; + +--echo # End of 5.1 tests + + diff --git a/mysql-test/t/bug39022.test b/mysql-test/t/bug39022.test index 1a1d10f5592..268b207e0e5 100644 --- a/mysql-test/t/bug39022.test +++ b/mysql-test/t/bug39022.test @@ -1,5 +1,6 @@ -- source include/have_log_bin.inc -- source include/have_innodb.inc +-- source include/not_binlog_format_row.inc --echo # --echo # Bug #39022: Mysql randomly crashing in lock_sec_rec_cons_read_sees @@ -49,10 +50,14 @@ connection thread2; --echo # in thread2 REAP; -connection default; ---echo # in default +disconnect thread2; +--source include/wait_until_disconnected.inc +connection thread1; +--echo # in thread1; disconnect thread1; -disconnect thread2; +--source include/wait_until_disconnected.inc + +connection default; DROP TABLE t1,t2; diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index cdf274190dd..b31fa83588b 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1807,16 +1807,16 @@ unlock tables; drop table t1; # -# Bug#41441 repair csv table crashes debug server -# -# Note: The test should be removed after Bug#33717 is fixed +# Bug#33717 INSERT...(default) fails for enum. Crashes CSV tables, loads spaces for MyISAM +# +CREATE TABLE t1 (e enum('foo','bar') NOT NULL) ENGINE = CSV; +INSERT INTO t1 VALUES(); +INSERT INTO t1 VALUES(default); +INSERT INTO t1 VALUES(0); +INSERT INTO t1 VALUES(3); +INSERT INTO t1 VALUES(-1); +SELECT * FROM t1; +DROP TABLE t1; -create table t1(a enum ('a') not null) engine=csv; -insert into t1 values (2); ---error ER_CRASHED_ON_USAGE -select * from t1 limit 1; -repair table t1; -select * from t1 limit 1; -drop table t1; --echo End of 5.1 tests diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test index 2f51fafd6a6..7bbc470137a 100644 --- a/mysql-test/t/delete.test +++ b/mysql-test/t/delete.test @@ -291,6 +291,21 @@ DELETE FROM t1 ORDER BY (f1(10)) LIMIT 1; DROP TABLE t1; DROP FUNCTION f1; + +--echo # +--echo # Bug #49552 : sql_buffer_result cause crash + not found records +--echo # in multitable delete/subquery +--echo # + +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1),(2),(3); +SET SESSION SQL_BUFFER_RESULT=1; +DELETE t1 FROM (SELECT SUM(a) a FROM t1) x,t1; + +SET SESSION SQL_BUFFER_RESULT=DEFAULT; +SELECT * FROM t1; +DROP TABLE t1; + --echo End of 5.0 tests --echo # @@ -360,18 +375,4 @@ DELETE IGNORE FROM t1; DROP TABLE t1; ---echo # ---echo # Bug #49552 : sql_buffer_result cause crash + not found records ---echo # in multitable delete/subquery ---echo # - -CREATE TABLE t1(a INT); -INSERT INTO t1 VALUES (1),(2),(3); -SET SESSION SQL_BUFFER_RESULT=1; -DELETE t1 FROM (SELECT SUM(a) a FROM t1) x,t1; - -SET SESSION SQL_BUFFER_RESULT=DEFAULT; -SELECT * FROM t1; -DROP TABLE t1; - --echo End of 5.1 tests diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test index 77b49a8b1a5..3c2f7bbbe96 100644 --- a/mysql-test/t/explain.test +++ b/mysql-test/t/explain.test @@ -147,7 +147,27 @@ EXPLAIN SELECT DISTINCT 1 FROM t1, WHERE t1.a = d1.a; DROP TABLE t1; -# End of 5.0 tests. +--echo # +--echo # Bug#48295: +--echo # explain extended crash with subquery and ONLY_FULL_GROUP_BY sql_mode +--echo # + +CREATE TABLE t1 (f1 INT); + +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; + +# EXPLAIN EXTENDED (with subselect). used to crash. should give NOTICE. +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS +EXPLAIN EXTENDED SELECT 1 FROM t1 + WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t ); +SHOW WARNINGS; + +SET SESSION sql_mode=@old_sql_mode; + +DROP TABLE t1; + +--echo End of 5.0 tests. --echo # --echo # Bug#37870: Usage of uninitialized value caused failed assertion. @@ -168,23 +188,14 @@ SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR drop tables t1, t2; --echo # ---echo # Bug#48295: ---echo # explain extended crash with subquery and ONLY_FULL_GROUP_BY sql_mode +--echo # Bug#47669: Query showed by EXPLAIN EXTENDED gives different result from original query --echo # -CREATE TABLE t1 (f1 INT); - -SELECT @@session.sql_mode INTO @old_sql_mode; -SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; - -# EXPLAIN EXTENDED (with subselect). used to crash. should give NOTICE. ---error ER_MIX_OF_GROUP_FUNC_AND_FIELDS -EXPLAIN EXTENDED SELECT 1 FROM t1 - WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t ); -SHOW WARNINGS; - -SET SESSION sql_mode=@old_sql_mode; - -DROP TABLE t1; +CREATE TABLE t1 (c int); +INSERT INTO t1 VALUES (NULL); +CREATE TABLE t2 (d int); +INSERT INTO t2 VALUES (NULL), (0); +EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) FROM t1; +DROP TABLE t1, t2; --echo End of 5.1 tests. diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index e92f3e96303..cfb4cdc9ecd 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -693,4 +693,19 @@ SELECT 1 FROM t1 WHERE t1.a NOT IN DROP TABLE t1, t2; +# +# Bug #49487: crash with explain extended and group_concat in a derived table +# + +CREATE TABLE t1 (f1 INT); +INSERT INTO t1 VALUES (),(); + +EXPLAIN EXTENDED SELECT 1 FROM + (SELECT DISTINCT GROUP_CONCAT(td.f1) FROM t1,t1 AS td GROUP BY td.f1) AS d,t1; + +SELECT 1 FROM + (SELECT DISTINCT GROUP_CONCAT(td.f1) FROM t1,t1 AS td GROUP BY td.f1) AS d,t1; + +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/mysql-test/t/gis-rtree.test b/mysql-test/t/gis-rtree.test index c325b3bd223..3b341501ab6 100644 --- a/mysql-test/t/gis-rtree.test +++ b/mysql-test/t/gis-rtree.test @@ -902,4 +902,26 @@ SELECT 1 FROM t1 WHERE a >= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 DROP TABLE t1; +--echo # +--echo # Bug #51357: crash when using handler commands on spatial indexes +--echo # + +CREATE TABLE t1(a GEOMETRY NOT NULL,SPATIAL INDEX a(a)); +HANDLER t1 OPEN; +HANDLER t1 READ a FIRST; +HANDLER t1 READ a NEXT; +HANDLER t1 READ a PREV; +HANDLER t1 READ a LAST; +HANDLER t1 CLOSE; + +# second crash fixed when the tree has changed since the last search. +HANDLER t1 OPEN; +HANDLER t1 READ a FIRST; +INSERT INTO t1 VALUES (GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))')); +HANDLER t1 READ a NEXT; +HANDLER t1 CLOSE; + +DROP TABLE t1; + + --echo End of 5.0 tests. diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test index af9af4fe1fc..185ca4bdddb 100644 --- a/mysql-test/t/having.test +++ b/mysql-test/t/having.test @@ -442,4 +442,30 @@ INSERT INTO t1 VALUES (1, 1), (2,2), (3, NULL); SELECT b, COUNT(DISTINCT a) FROM t1 GROUP BY b HAVING b is NULL; DROP TABLE t1; + +--echo # +--echo # Bug#50995 Having clause on subquery result produces incorrect results. +--echo # + +CREATE TABLE t1 +( + id1 INT, + id2 INT NOT NULL, + INDEX id1(id2) +); + +INSERT INTO t1 SET id1=1, id2=1; +INSERT INTO t1 SET id1=2, id2=1; +INSERT INTO t1 SET id1=3, id2=1; + +SELECT t1.id1, +(SELECT 0 FROM DUAL + WHERE t1.id1=t1.id1) AS amount FROM t1 +WHERE t1.id2 = 1 +HAVING amount > 0 +ORDER BY t1.id1; + +DROP TABLE t1; + + --echo End of 5.0 tests diff --git a/mysql-test/t/innodb-autoinc.test b/mysql-test/t/innodb-autoinc.test index bb431408937..ef0359b78b0 100644 --- a/mysql-test/t/innodb-autoinc.test +++ b/mysql-test/t/innodb-autoinc.test @@ -631,3 +631,34 @@ REPLACE INTO t1 VALUES (-1); SELECT * FROM t1; SHOW CREATE TABLE t1; DROP TABLE t1; + +## +# 49497: Error 1467 (ER_AUTOINC_READ_FAILED) on inserting a negative value +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (-685113344), (1), (NULL), (NULL); +SELECT * FROM t1; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (-685113344), (2), (NULL), (NULL); +SELECT * FROM t1; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL), (2), (-685113344), (NULL); +INSERT INTO t1 VALUES (4), (5), (6), (NULL); +SELECT * FROM t1; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (NULL), (2), (-685113344), (5); +SELECT * FROM t1; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (c1 INTEGER AUTO_INCREMENT, PRIMARY KEY (c1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1), (2), (-685113344), (NULL); +SELECT * FROM t1; +SHOW CREATE TABLE t1; +DROP TABLE t1; diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index d9fecccfbdc..75fff9656e2 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -545,5 +545,35 @@ CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb ; SELECT 1 FROM t1 JOIN t1 a USING(a) GROUP BY t1.a,t1.a; DROP TABLE t1; +--echo # +--echo # Bug#50843: Filesort used instead of clustered index led to +--echo # performance degradation. +--echo # +create table t1(f1 int not null primary key, f2 int) engine=innodb; +create table t2(f1 int not null, key (f1)) engine=innodb; +insert into t1 values (1,1),(2,2),(3,3); +insert into t2 values (1),(2),(3); +explain select t1.* from t1 left join t2 using(f1) group by t1.f1; +drop table t1,t2; +--echo # + + +--echo # +--echo # Bug #39653: find_shortest_key in sql_select.cc does not consider +--echo # clustered primary keys +--echo # + +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c INT, d INT, e INT, f INT, + KEY (b,c)) ENGINE=INNODB; + +INSERT INTO t1 VALUES (1,1,1,1,1,1), (2,2,2,2,2,2), (3,3,3,3,3,3), + (4,4,4,4,4,4), (5,5,5,5,5,5), (6,6,6,6,6,6), + (7,7,7,7,7,7), (8,8,8,8,8,8), (9,9,9,9,9,9), + (11,11,11,11,11,11); + +--query_vertical EXPLAIN SELECT COUNT(*) FROM t1 + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test index 645321a3a5e..761121313e5 100644 --- a/mysql-test/t/join.test +++ b/mysql-test/t/join.test @@ -816,3 +816,16 @@ CREATE TABLE mm1(a CHAR(9),b INT,KEY(b),KEY(a)) ENGINE=MERGE UNION=(t1,t2); SELECT t1.a FROM mm1,t1; DROP TABLE t1, t2, mm1; + +--echo # +--echo # Bug #50335: Assertion `!(order->used & map)' in eq_ref_table +--echo # + +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)); +INSERT INTO t1 VALUES (0,0), (1,1); + +SELECT * FROM t1 STRAIGHT_JOIN t1 t2 ON t1.a=t2.a AND t1.a=t2.b ORDER BY t2.a, t1.a; + +DROP TABLE t1; + +--echo End of 5.1 tests diff --git a/mysql-test/t/log_tables_upgrade.test b/mysql-test/t/log_tables_upgrade.test new file mode 100644 index 00000000000..5d1b2b5aed6 --- /dev/null +++ b/mysql-test/t/log_tables_upgrade.test @@ -0,0 +1,32 @@ +--source include/not_embedded.inc +--source include/have_csv.inc + +# Only run test if "mysql_upgrade" is found +--require r/have_mysql_upgrade.result +--disable_query_log +select LENGTH("$MYSQL_UPGRADE")>0 as have_mysql_upgrade; +--enable_query_log + +--echo # +--echo # Bug#49823: mysql_upgrade fatal error due to general_log / slow_low CSV NULL +--echo # + +USE test; + +let $MYSQLD_DATADIR= `SELECT @@datadir`; +copy_file std_data/bug49823.frm $MYSQLD_DATADIR/test/bug49823.frm; +copy_file std_data/bug49823.CSM $MYSQLD_DATADIR/test/bug49823.CSM; +copy_file std_data/bug49823.CSV $MYSQLD_DATADIR/test/bug49823.CSV; + +SET @saved_general_log = @@GLOBAL.general_log; +SET GLOBAL general_log = OFF; +USE mysql; +FLUSH TABLES; +REPAIR TABLE test.bug49823; +RENAME TABLE general_log TO renamed_general_log; +RENAME TABLE test.bug49823 TO general_log; +--exec $MYSQL_UPGRADE --skip-verbose --force 2>&1 +DROP TABLE general_log; +RENAME TABLE renamed_general_log TO general_log; +SET GLOBAL general_log = @saved_general_log; +USE test; diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index d12dbce1cc1..ea7ddc88b77 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1587,5 +1587,20 @@ REPLACE INTO t1 VALUES CHECK TABLE t1; DROP TABLE t1; ---echo End of 5.1 tests +--echo # +--echo # Bug#51304: checksum table gives different results +--echo # for same data when using bit fields +--echo # +CREATE TABLE t1(a INT, b BIT(1)); +INSERT INTO t1 VALUES(1, 0), (2, 1); +CREATE TABLE t2 SELECT * FROM t1; +--copy_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/t3.frm +--copy_file $MYSQLD_DATADIR/test/t1.MYD $MYSQLD_DATADIR/test/t3.MYD +--copy_file $MYSQLD_DATADIR/test/t1.MYI $MYSQLD_DATADIR/test/t3.MYI +CHECKSUM TABLE t1 EXTENDED; +CHECKSUM TABLE t2 EXTENDED; +CHECKSUM TABLE t3 EXTENDED; +DROP TABLE t1, t2, t3; + +--echo End of 5.1 tests diff --git a/mysql-test/t/mysql_upgrade.test b/mysql-test/t/mysql_upgrade.test index 24a1d2e1b5d..6c01f3b2027 100644 --- a/mysql-test/t/mysql_upgrade.test +++ b/mysql-test/t/mysql_upgrade.test @@ -32,7 +32,7 @@ if (`SELECT $VALGRIND_TEST`) # expected binaries it uses. # --echo Run mysql_upgrade once ---exec $MYSQL_UPGRADE --skip-verbose 2>&1 +--exec $MYSQL_UPGRADE --skip-verbose --force 2>&1 # It should have created a file in the MySQL Servers datadir let $MYSQLD_DATADIR= `select @@datadir`; diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index bcf33aa8c27..25293ff29e7 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -605,6 +605,15 @@ echo ; --error 1 --exec echo "--exec " | $MYSQL_TEST 2>&1 +# Multi-line exec +exec $MYSQL + test -e "select 1"; +exec $MYSQL test -e "select + 2"; +let $query = select 3 + as X; +exec $MYSQL test -e "$query"; + # ---------------------------------------------------------------------------- # Test let command # ---------------------------------------------------------------------------- @@ -911,6 +920,28 @@ sleep 0.5; sleep 1; real_sleep 1; +# Parameter from variable, legal and illegal +let $sleep_var= 0.1; +sleep $sleep_var; +let $sleep_var= 1; +--real_sleep $sleep_var + +--write_file $MYSQL_TMP_DIR/sleep.inc +let $sleep_var= xyz; +--sleep $sleep_var +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQL_TMP_DIR/sleep.inc 2>&1 +--remove_file $MYSQL_TMP_DIR/sleep.inc + +--write_file $MYSQL_TMP_DIR/sleep.inc +let $sleep_var= xyz; +real_sleep $sleep_var; +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQL_TMP_DIR/sleep.inc 2>&1 +--remove_file $MYSQL_TMP_DIR/sleep.inc + # Missing parameter --error 1 --exec echo "sleep ;" | $MYSQL_TEST 2>&1 @@ -1006,6 +1037,37 @@ echo test3stop --delimiter ; echo test4; +# ---------------------------------------------------------------------------- +# Test that delimiter within if() works in in various combinations +# ---------------------------------------------------------------------------- + +if (0) +{ + delimiter ||; + echo false-inner|| + if (0) + { + delimiter *|| + echo false-innerer* + delimiter ||* + } + echo false-inner again|| +} +echo outer; +if (1) +{ + delimiter /; + echo true-inner/ + if (0) + { + delimiter %/ + echo true-innerer% + } + echo true-inner again/ +} +echo true-outer/ +delimiter ;/ + # ---------------------------------------------------------------------------- # Test if @@ -1285,6 +1347,17 @@ select "a" as col1, "c" as col2; --error 1 --exec echo "--replace_column 1 b c " | $MYSQL_TEST 2>&1 +let $long_rep= 1234567890123456789012345678901234567890; +let $long_rep= $long_rep,$long_rep; +let $long_rep= $long_rep,$long_rep; +let $long_rep= $long_rep,$long_rep; +let $long_rep= $long_rep,$long_rep; +let $long_rep= $long_rep,$long_rep; + +# This tests from strings > 1024 (here 1311) + +--replace_result $long_rep LONG_STRING +eval select "$long_rep" as x; # ---------------------------------------------------------------------------- # Test sync_with_master @@ -1606,6 +1679,57 @@ select * from t1; drop table t1; # ---------------------------------------------------------------------------- +# Tests of send +# ---------------------------------------------------------------------------- + +create table t1 ( f1 char(10)); +insert into t1 values ("Abcd"); + +# 1. Basic test + +send select * from t1; +reap; + +# 2. Test with error + +--send select * from t2; +--error ER_NO_SUCH_TABLE +--reap + +# 3. test send of next stmt + +--send +select * from t1; +--reap + +# 4. Non-query stmt betwen send and reap allowed + +--send select * from t1; +--sleep 0.05 +--echo Result coming up +--reap + +# 5. Test of send_eval + +--let $my_stmt= select * from t1; +--send_eval $my_stmt +--reap + +# 6. Test that mysqltest does not allow query stmt between send and reap +# Untestable directly as it causes mysqltest to fail + +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.in +--send select * from t1; +select 1; +--reap +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.in 2>&1 +remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.in; + +drop table t1; + +# ---------------------------------------------------------------------------- # test for remove_file # ---------------------------------------------------------------------------- @@ -1616,6 +1740,19 @@ drop table t1; remove_file non_existing_file; # ---------------------------------------------------------------------------- +# test for remove_files_wildcard +# ---------------------------------------------------------------------------- + +--error 1 +--exec echo "remove_files_wildcard ;" | $MYSQL_TEST 2>&1 + +--error 1 +remove_files_wildcard non_existing_dir; + +--error 1 +remove_files_wildcard non_existing_dir non_existing_file; + +# ---------------------------------------------------------------------------- # test for write_file # ---------------------------------------------------------------------------- --error 1 @@ -1905,6 +2042,20 @@ perl; print "hello\n"; EOF +# Test perl within while, also with if being false first iteration +let $outer= 3; +let $ifval= 0; +while ($outer) { + if ($ifval) { + perl UNTIL; + my $val= 5; + print "val is $val\n"; +UNTIL + } + inc $ifval; + dec $outer; +} + # ---------------------------------------------------------------------------- # test for die # ---------------------------------------------------------------------------- @@ -2045,6 +2196,44 @@ INSERT INTO t1 SELECT f1 - 512 FROM t1; SELECT * FROM t1; --enable_result_log DROP TABLE t1; + +# ---------------------------------------------------------------------------- +# test for lowercase_result +# ---------------------------------------------------------------------------- + +# 1. Basic test +--lowercase_result +SELECT "500g BLÅBÆRSYLTETØY" AS "WILL BE lower cased"; + +# 2. test that it does not apply to next statement +SELECT "UPPER" AS "WILL NOT BE lower cased"; + +# 3. test that it does not affect non-SQL or the following statement +--lowercase_result +--echo UP +SELECT 0 as "UP AGAIN"; + +# 4. test that it works with eval and variables +let $lower_stmt=SELECT "ABCdef" AS "uvwXYZ"; +--lowercase_result +eval $lower_stmt; + +# 5. test that it works in combination with sort +sorted_result; +lowercase_result; +SELECT "Xyz" AS Name UNION SELECT "Abc" as Name ORDER BY Name DESC; + +# 6. Test combination with replace, and that lower casing is done first +--lowercase_result +--replace_result old new +SELECT 1 as "SOME OLD TEXT"; + +# 7. Test missing lower casing of "unknown" characters +--character_set utf8 +--lowercase_result +SELECT 0 as "WILL NOT lower case ÄËÐ"; +--character_set latin1 + # ---------------------------------------------------------------------------- # Some coverage tests # ---------------------------------------------------------------------------- @@ -2230,9 +2419,14 @@ rmdir $MYSQLTEST_VARDIR/tmp/testdir; cat_file $MYSQLTEST_VARDIR/tmp/testdir/file3.txt; -remove_file $MYSQLTEST_VARDIR/tmp/testdir/file1.txt; -remove_file $MYSQLTEST_VARDIR/tmp/testdir/file2.txt; -remove_file $MYSQLTEST_VARDIR/tmp/testdir/file3.txt; +list_files_write_file $MYSQLTEST_VARDIR/tmp/testdir/file11.txt $MYSQLTEST_VARDIR/tmp/testdir file?.txt; +remove_files_wildcard $MYSQLTEST_VARDIR/tmp/testdir file?.txt; +list_files_write_file $MYSQLTEST_VARDIR/tmp/testdir/dir-list.txt $MYSQLTEST_VARDIR/tmp/testdir file*.txt; +cat_file $MYSQLTEST_VARDIR/tmp/testdir/dir-list.txt; +remove_files_wildcard $MYSQLTEST_VARDIR/tmp/testdir file*.txt; +list_files $MYSQLTEST_VARDIR/tmp/testdir; +remove_files_wildcard $MYSQLTEST_VARDIR/tmp/testdir; +list_files $MYSQLTEST_VARDIR/tmp/testdir; rmdir $MYSQLTEST_VARDIR/tmp/testdir; # diff --git a/mysql-test/t/partition_debug_sync.test b/mysql-test/t/partition_debug_sync.test new file mode 100644 index 00000000000..69bc86a8bb7 --- /dev/null +++ b/mysql-test/t/partition_debug_sync.test @@ -0,0 +1,81 @@ +#--disable_abort_on_error +# +# Test for the partition storage engine which require DEBUG_SYNC feature to +# Created by Mattias Jonsson +# +--source include/have_partition.inc +--source include/have_debug_sync.inc + +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +SET DEBUG_SYNC= 'RESET'; +--enable_warnings + +--echo # +--echo # Bug#42438: Crash ha_partition::change_table_ptr +--echo # Test when remove partitioning is done while drop table is waiting +--echo # for the table. +connect(con1, localhost, root,,); +--echo # Con 1 +SET DEBUG_SYNC= 'RESET'; +CREATE TABLE t1 +(a INTEGER, + b INTEGER NOT NULL, + KEY (b)) +ENGINE = MYISAM +/*!50100 PARTITION BY RANGE (a) +(PARTITION p0 VALUES LESS THAN (2), + PARTITION p1 VALUES LESS THAN (20), + PARTITION p2 VALUES LESS THAN (100), + PARTITION p3 VALUES LESS THAN MAXVALUE ) */; +SET DEBUG_SYNC= 'alter_table_before_create_table_no_lock SIGNAL removing_partitioning WAIT_FOR waiting_for_alter'; +SET DEBUG_SYNC= 'alter_table_before_main_binlog SIGNAL partitioning_removed'; +--send ALTER TABLE t1 REMOVE PARTITIONING +connection default; +--echo # Con default +SET DEBUG_SYNC= 'now WAIT_FOR removing_partitioning'; +SET DEBUG_SYNC= 'waiting_for_table SIGNAL waiting_for_alter'; +SET DEBUG_SYNC= 'rm_table_part2_before_delete_table WAIT_FOR partitioning_removed'; +DROP TABLE IF EXISTS t1; +--echo # Con 1 +connection con1; +--reap +connection default; +SET DEBUG_SYNC= 'RESET'; +connection con1; +SET DEBUG_SYNC= 'RESET'; + +--echo # +--echo # Bug#42438: Crash ha_partition::change_table_ptr +--echo # Test when remove partitioning is failing due to drop table is already +--echo # in progress. +CREATE TABLE t2 +(a INTEGER, + b INTEGER NOT NULL, + KEY (b)) +ENGINE = MYISAM +/*!50100 PARTITION BY RANGE (a) +(PARTITION p0 VALUES LESS THAN (2), + PARTITION p1 VALUES LESS THAN (20), + PARTITION p2 VALUES LESS THAN (100), + PARTITION p3 VALUES LESS THAN MAXVALUE ) */; +SET DEBUG_SYNC= 'before_lock_tables_takes_lock SIGNAL removing_partitions WAIT_FOR waiting_for_alter'; +SET DEBUG_SYNC= 'alter_table_before_rename_result_table WAIT_FOR delete_done'; +--send ALTER TABLE t2 REMOVE PARTITIONING +connection default; +--echo # Con default +SET DEBUG_SYNC= 'now WAIT_FOR removing_partitions'; +SET DEBUG_SYNC= 'waiting_for_table SIGNAL waiting_for_alter'; +SET DEBUG_SYNC= 'rm_table_part2_before_binlog SIGNAL delete_done'; +DROP TABLE IF EXISTS t2; +--echo # Con 1 +connection con1; +--error ER_NO_SUCH_TABLE +--reap +SET DEBUG_SYNC= 'RESET'; +disconnect con1; +connection default; +--echo # Con default +SET DEBUG_SYNC= 'RESET'; + +--echo End of 5.1 tests diff --git a/mysql-test/t/partition_innodb_semi_consistent.test b/mysql-test/t/partition_innodb_semi_consistent.test index 6a6a7cf958e..2711d79f194 100644 --- a/mysql-test/t/partition_innodb_semi_consistent.test +++ b/mysql-test/t/partition_innodb_semi_consistent.test @@ -187,6 +187,7 @@ SELECT * FROM t1; --echo # Switch to connection con2 connection con2; +reap; SELECT * FROM t1; connection default; diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index 530389b3ab9..8bedf9357ef 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -425,4 +425,17 @@ select hex(a) from t1; show create table t1; drop table t1; +--echo # +--echo # Bug#50591 bit(31) causes Duplicate entry '1-NULL' for key 'group_key' +--echo # +CREATE TABLE t1(a INT, b BIT(7) NOT NULL); +INSERT INTO t1 VALUES (NULL, 0),(NULL, 0); +SELECT SUM(a) FROM t1 GROUP BY b, a; +DROP TABLE t1; + +CREATE TABLE t1(a INT, b BIT(7) NOT NULL, c BIT(8) NOT NULL); +INSERT INTO t1 VALUES (NULL, 0, 0),(NULL, 0, 0); +SELECT SUM(a) FROM t1 GROUP BY c, b, a; +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/t/variables+c.test b/mysql-test/t/variables_community.test index 0092d34133d..0092d34133d 100644 --- a/mysql-test/t/variables+c.test +++ b/mysql-test/t/variables_community.test diff --git a/mysys/charset.c b/mysys/charset.c index b1b91d716ba..9678febc9ba 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -400,6 +400,7 @@ static void *cs_alloc(size_t size) static my_pthread_once_t charsets_initialized= MY_PTHREAD_ONCE_INIT; +static my_pthread_once_t charsets_template= MY_PTHREAD_ONCE_INIT; static void init_available_charsets(void) { @@ -427,6 +428,11 @@ static void init_available_charsets(void) } +void free_charsets(void) +{ + charsets_initialized= charsets_template; +} + uint get_collation_number(const char *name) { my_pthread_once(&charsets_initialized, init_available_charsets); diff --git a/mysys/my_init.c b/mysys/my_init.c index 453c72f999f..a60927be693 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -165,6 +165,7 @@ void my_end(int infoflag) my_print_open_files(); } } + free_charsets(); my_error_unregister_all(); my_once_free(); diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 0292617c7a5..1aa24c5d432 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -110,7 +110,8 @@ mysqlbug: ${top_builddir}/config.status mysqlbug.sh mysql_fix_privilege_tables.sql: mysql_system_tables.sql \ mysql_system_tables_fix.sql @echo "Building $@"; - @cat mysql_system_tables.sql mysql_system_tables_fix.sql > $@ + @cat $(srcdir)/mysql_system_tables.sql \ + $(srcdir)/mysql_system_tables_fix.sql > $@ # # Build mysql_fix_privilege_tables_sql.c from @@ -123,7 +124,7 @@ mysql_fix_privilege_tables_sql.c: comp_sql.c mysql_fix_privilege_tables.sql sleep 2 $(top_builddir)/scripts/comp_sql$(EXEEXT) \ mysql_fix_privilege_tables \ - $(top_srcdir)/scripts/mysql_fix_privilege_tables.sql $@ + $(top_builddir)/scripts/mysql_fix_privilege_tables.sql $@ SUFFIXES = .sh diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 20b7973cb4e..c5e4a1f1cba 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -410,8 +410,7 @@ else echo "Try 'mysqld --help' if you have problems with paths. Using --log" echo "gives you a log in $ldata that may be helpful." echo - echo "The latest information about MySQL is available on the web at" - echo "http://www.mysql.com/. Please consult the MySQL manual section" + echo "Please consult the MySQL manual section" echo "'Problems running mysql_install_db', and the manual section that" echo "describes problems on your OS. Another information source are the" echo "MySQL email archives available at http://lists.mysql.com/." @@ -470,9 +469,6 @@ then echo echo "Please report any problems with the $scriptdir/mysqlbug script!" echo - echo "The latest information about MySQL is available at http://www.mysql.com/" - echo "Support MySQL by buying support/licenses from http://shop.mysql.com/" - echo fi exit 0 diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index 4260aee9142..deeb4d4de82 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -221,12 +221,29 @@ ALTER TABLE func SET @old_log_state = @@global.general_log; SET GLOBAL general_log = 'OFF'; -ALTER TABLE general_log MODIFY COLUMN server_id INTEGER UNSIGNED NOT NULL; +ALTER TABLE general_log + MODIFY event_time TIMESTAMP NOT NULL, + MODIFY user_host MEDIUMTEXT NOT NULL, + MODIFY thread_id INTEGER NOT NULL, + MODIFY server_id INTEGER UNSIGNED NOT NULL, + MODIFY command_type VARCHAR(64) NOT NULL, + MODIFY argument MEDIUMTEXT NOT NULL; SET GLOBAL general_log = @old_log_state; SET @old_log_state = @@global.slow_query_log; SET GLOBAL slow_query_log = 'OFF'; -ALTER TABLE slow_log MODIFY COLUMN server_id INTEGER UNSIGNED NOT NULL; +ALTER TABLE slow_log + MODIFY start_time TIMESTAMP NOT NULL, + MODIFY user_host MEDIUMTEXT NOT NULL, + MODIFY query_time TIME NOT NULL, + MODIFY lock_time TIME NOT NULL, + MODIFY rows_sent INTEGER NOT NULL, + MODIFY rows_examined INTEGER NOT NULL, + MODIFY db VARCHAR(512) NOT NULL, + MODIFY last_insert_id INTEGER NOT NULL, + MODIFY insert_id INTEGER NOT NULL, + MODIFY server_id INTEGER UNSIGNED NOT NULL, + MODIFY sql_text MEDIUMTEXT NOT NULL; SET GLOBAL slow_query_log = @old_log_state; # diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh index 528a1ca2e98..3d3853bcb22 100644 --- a/scripts/mysqld_multi.sh +++ b/scripts/mysqld_multi.sh @@ -71,7 +71,6 @@ sub main print "WARNING: --config-file is deprecated and will be removed\n"; print "in MySQL 5.6. Please use --defaults-extra-file instead\n"; } - } } foreach (@defaults_options) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 7b9ecd7d902..1d4290c6ab0 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1746,13 +1746,23 @@ void ha_partition::update_create_info(HA_CREATE_INFO *create_info) void ha_partition::change_table_ptr(TABLE *table_arg, TABLE_SHARE *share) { - handler **file_array= m_file; + handler **file_array; table= table_arg; table_share= share; - do + /* + m_file can be NULL when using an old cached table in DROP TABLE, when the + table just has REMOVED PARTITIONING, see Bug#42438 + */ + if (m_file) { - (*file_array)->change_table_ptr(table_arg, share); - } while (*(++file_array)); + file_array= m_file; + DBUG_ASSERT(*file_array); + do + { + (*file_array)->change_table_ptr(table_arg, share); + } while (*(++file_array)); + } + if (m_added_file && m_added_file[0]) { /* if in middle of a drop/rename etc */ @@ -6055,7 +6065,13 @@ void ha_partition::print_error(int error, myf errflag) if (error == HA_ERR_NO_PARTITION_FOUND) m_part_info->print_no_partition_found(table); else - m_file[m_last_part]->print_error(error, errflag); + { + /* In case m_file has not been initialized, like in bug#42438 */ + if (m_file) + m_file[m_last_part]->print_error(error, errflag); + else + handler::print_error(error, errflag); + } DBUG_VOID_RETURN; } @@ -6065,7 +6081,12 @@ bool ha_partition::get_error_message(int error, String *buf) DBUG_ENTER("ha_partition::get_error_message"); /* Should probably look for my own errors first */ - DBUG_RETURN(m_file[m_last_part]->get_error_message(error, buf)); + + /* In case m_file has not been initialized, like in bug#42438 */ + if (m_file) + DBUG_RETURN(m_file[m_last_part]->get_error_message(error, buf)); + DBUG_RETURN(handler::get_error_message(error, buf)); + } diff --git a/sql/item.cc b/sql/item.cc index df266434f72..04496338b8f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2209,14 +2209,14 @@ String *Item_int::val_str(String *str) { // following assert is redundant, because fixed=1 assigned in constructor DBUG_ASSERT(fixed == 1); - str->set(value, &my_charset_bin); + str->set_int(value, unsigned_flag, &my_charset_bin); return str; } void Item_int::print(String *str, enum_query_type query_type) { // my_charset_bin is good enough for numbers - str_value.set(value, &my_charset_bin); + str_value.set_int(value, unsigned_flag, &my_charset_bin); str->append(str_value); } @@ -5690,9 +5690,14 @@ void Item_field::print(String *str, enum_query_type query_type) char buff[MAX_FIELD_WIDTH]; String tmp(buff,sizeof(buff),str->charset()); field->val_str(&tmp); - str->append('\''); - str->append(tmp); - str->append('\''); + if (field->is_null()) + str->append("NULL"); + else + { + str->append('\''); + str->append(tmp); + str->append('\''); + } return; } Item_ident::print(str, query_type); @@ -6488,7 +6493,8 @@ int Item_default_value::save_in_field(Field *field_arg, bool no_conversions) { if (!arg) { - if (field_arg->flags & NO_DEFAULT_VALUE_FLAG) + if (field_arg->flags & NO_DEFAULT_VALUE_FLAG && + field_arg->real_type() != MYSQL_TYPE_ENUM) { if (field_arg->reset()) { diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 38025ff0af5..425f54fb079 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1474,9 +1474,21 @@ public: Item_cond(THD *thd, Item_cond *item); Item_cond(List<Item> &nlist) :Item_bool_func(), list(nlist), abort_on_null(0) {} - bool add(Item *item) { return list.push_back(item); } - bool add_at_head(Item *item) { return list.push_front(item); } - void add_at_head(List<Item> *nlist) { list.prepand(nlist); } + bool add(Item *item) + { + DBUG_ASSERT(item); + return list.push_back(item); + } + bool add_at_head(Item *item) + { + DBUG_ASSERT(item); + return list.push_front(item); + } + void add_at_head(List<Item> *nlist) + { + DBUG_ASSERT(nlist->elements); + list.prepand(nlist); + } bool fix_fields(THD *, Item **ref); enum Type type() const { return COND_ITEM; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 4ab8e75ddf5..142e90639e8 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3402,6 +3402,8 @@ String* Item_func_group_concat::val_str(String* str) void Item_func_group_concat::print(String *str, enum_query_type query_type) { + /* orig_args is not filled with valid values until fix_fields() */ + Item **pargs= fixed ? orig_args : args; str->append(STRING_WITH_LEN("group_concat(")); if (distinct) str->append(STRING_WITH_LEN("distinct ")); @@ -3409,7 +3411,7 @@ void Item_func_group_concat::print(String *str, enum_query_type query_type) { if (i) str->append(','); - args[i]->print(str, query_type); + pargs[i]->print(str, query_type); } if (arg_count_order) { diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index ded4d28ca29..4248c2e6b4f 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -876,7 +876,7 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, value= value*LL(10) + (longlong) (*str - '0'); if (transform_msec && i == count - 1) // microseconds always last { - int msec_length= 6 - (int)(str - start); + int msec_length= 6 - (int) (str - start); if (msec_length > 0) value*= (long)log_10_int[msec_length]; } diff --git a/sql/log_event.cc b/sql/log_event.cc index 2398f33dc23..8e8e7bd4338 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8753,7 +8753,7 @@ static bool record_compare(TABLE *table) DBUG_DUMP("record[1]", table->record[1], table->s->reclength); bool result= FALSE; - uchar saved_x[2], saved_filler[2]; + uchar saved_x[2]= {0, 0}, saved_filler[2]= {0, 0}; if (table->s->null_bytes > 0) { diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 313916c9818..0f501fd1514 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -337,7 +337,7 @@ static bool record_compare(TABLE *table) */ bool result= FALSE; - uchar saved_x[2], saved_filler[2]; + uchar saved_x[2]= {0, 0}, saved_filler[2]= {0, 0}; if (table->s->null_bytes > 0) { diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a483b9e2381..f658a7c8c3c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1287,6 +1287,7 @@ void clean_up(bool print_message) lex_free(); /* Free some memory */ item_create_cleanup(); set_var_free(); + free_charsets(); if (!opt_noacl) { #ifdef HAVE_DLOPEN @@ -6076,8 +6077,8 @@ each time the SQL thread starts.", TC_LOG_PAGE_SIZE, 0}, #endif {"log-update", OPT_UPDATE_LOG, - "The update log is deprecated since version 5.0, is replaced by the binary \ -log and this option justs turns on --log-bin instead.", + "The update log is deprecated since version 5.0, is replaced by the binary " + "log and this option just turns on --log-bin instead.", (uchar**) &opt_update_logname, (uchar**) &opt_update_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-warnings", 'W', "Log some not critical warnings to the log file.", @@ -6337,7 +6338,10 @@ thread is in the relay logs.", "Tells the slave thread to not replicate to the specified database. To specify more than one database to ignore, use the directive multiple times, once for each database. This option will not work if you use cross database updates. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-ignore-table=db_name.%. ", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE, - "Tells the slave thread to not replicate to the specified table. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-datbase updates, in contrast to replicate-ignore-db.", + "Tells the slave thread to not replicate to the specified table. To specify " + "more than one table to ignore, use the directive multiple times, once for " + "each table. This will work for cross-database updates, in contrast to " + "replicate-ignore-db.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB, "Updates to a database with a different name than the original. Example: replicate-rewrite-db=master_db_name->slave_db_name.", @@ -6359,7 +6363,13 @@ Can't be set to 1 if --log-slave-updates is used.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, // In replication, we may need to tell the other servers how to connect {"report-host", OPT_REPORT_HOST, - "Hostname or IP of the slave to be reported to to the master during slave registration. Will appear in the output of SHOW SLAVE HOSTS. Leave unset if you do not want the slave to register itself with the master. Note that it is not sufficient for the master to simply read the IP of the slave off the socket once the slave connects. Due to NAT and other routing issues, that IP may not be valid for connecting to the slave from the master or other hosts.", + "Hostname or IP of the slave to be reported to the master during slave " + "registration. Will appear in the output of SHOW SLAVE HOSTS. Leave unset " + "if you do not want the slave to register itself with the master. Note that " + "it is not sufficient for the master to simply read the IP of the slave " + "from the socket once the slave connects. Due to NAT and other routing " + "issues, that IP may not be valid for connecting to the slave from the " + "master or other hosts.", (uchar**) &report_host, (uchar**) &report_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"report-password", OPT_REPORT_PASSWORD, "Undocumented.", @@ -6664,7 +6674,10 @@ log and this option does nothing anymore.", (uchar**) &max_system_variables.keep_files_on_create, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"key_buffer_size", OPT_KEY_BUFFER_SIZE, - "The size of the buffer used for index blocks for MyISAM tables. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.", + "The size of the buffer used for index blocks for MyISAM tables. Increase " + "this to get better index handling (for all reads and multiple writes) to " + "as much as you can afford; 1GB on a 4GB machine that mainly runs MySQL is " + "quite common.", (uchar**) &dflt_key_cache_var.param_buff_size, (uchar**) 0, 0, (GET_ULL | GET_ASK_ADDR), @@ -6835,7 +6848,9 @@ The minimum value for this variable is 4096.", (uchar**) &myisam_mmap_size, (uchar**) &myisam_mmap_size, 0, GET_ULL, REQUIRED_ARG, SIZE_T_MAX, MEMMAP_EXTRA_MARGIN, SIZE_T_MAX, 0, 1, 0}, {"myisam_repair_threads", OPT_MYISAM_REPAIR_THREADS, - "Number of threads to use when repairing MyISAM tables. The value of 1 disables parallel repair.", + "Specifies whether several threads should be used when repairing MyISAM " + "tables. For values > 1, one thread is used per index. The value of 1 " + "disables parallel repair.", (uchar**) &global_system_variables.myisam_repair_threads, (uchar**) &max_system_variables.myisam_repair_threads, 0, GET_ULONG, REQUIRED_ARG, 1, 1, ULONG_MAX, 0, 1, 0}, @@ -7162,7 +7177,8 @@ static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff) var->type= SHOW_MY_BOOL; pthread_mutex_lock(&LOCK_active_mi); var->value= buff; - *((my_bool *)buff)= (my_bool) (active_mi && active_mi->slave_running && + *((my_bool *)buff)= (my_bool) (active_mi && + active_mi->slave_running == MYSQL_SLAVE_RUN_CONNECT && active_mi->rli.slave_running); pthread_mutex_unlock(&LOCK_active_mi); return 0; diff --git a/sql/share/Makefile.am b/sql/share/Makefile.am index 68b393e619f..357f9ac0876 100644 --- a/sql/share/Makefile.am +++ b/sql/share/Makefile.am @@ -22,7 +22,7 @@ dist-hook: test -d $(distdir)/$$dir || mkdir $(distdir)/$$dir; \ $(INSTALL_DATA) $(srcdir)/$$dir/*.* $(distdir)/$$dir; \ done; \ - sleep 1 ; touch $(srcdir)/*/errmsg.sys + sleep 1 ; touch $(builddir)/*/errmsg.sys $(INSTALL_DATA) $(srcdir)/charsets/README $(distdir)/charsets $(INSTALL_DATA) $(srcdir)/charsets/Index.xml $(distdir)/charsets @@ -39,11 +39,11 @@ install-data-local: for lang in @AVAILABLE_LANGUAGES@; \ do \ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)/$$lang; \ - $(INSTALL_DATA) $(srcdir)/$$lang/errmsg.sys \ + $(INSTALL_DATA) $(builddir)/$$lang/errmsg.sys \ $(DESTDIR)$(pkgdatadir)/$$lang/errmsg.sys; \ done $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)/charsets - $(INSTALL_DATA) $(srcdir)/errmsg.txt \ + $(INSTALL_DATA) $(builddir)/errmsg.txt \ $(DESTDIR)$(pkgdatadir)/errmsg.txt; \ $(INSTALL_DATA) $(srcdir)/charsets/README $(DESTDIR)$(pkgdatadir)/charsets/README $(INSTALL_DATA) $(srcdir)/charsets/*.xml $(DESTDIR)$(pkgdatadir)/charsets @@ -53,7 +53,7 @@ uninstall-local: @RM@ -f -r $(DESTDIR)$(pkgdatadir) distclean-local: - @RM@ -f */errmsg.sys + @RM@ -f $(builddir)/*/errmsg.sys # Do nothing link_sources: diff --git a/sql/slave.cc b/sql/slave.cc index 271b3635cf1..a89ac2e682b 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2557,6 +2557,7 @@ pthread_handler_t handle_slave_io(void *arg) connected: + DBUG_SYNC_POINT("debug_lock.before_get_running_status_yes", 10); // TODO: the assignment below should be under mutex (5.0) mi->slave_running= MYSQL_SLAVE_RUN_CONNECT; thd->slave_net = &mysql->net; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 06e4b1d3e63..f75a73c15a8 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2169,6 +2169,7 @@ void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond) proc_info=thd->proc_info; thd_proc_info(thd, "Waiting for table"); DBUG_ENTER("wait_for_condition"); + DEBUG_SYNC(thd, "waiting_for_table"); if (!thd->killed) (void) pthread_cond_wait(cond, mutex); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a3ce50fe4ee..bc68d3b03e0 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7028,9 +7028,11 @@ eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab) } if (order) { - found++; - DBUG_ASSERT(!(order->used & map)); - order->used|=map; + if (!(order->used & map)) + { + found++; + order->used|= map; + } continue; // Used in ORDER BY } if (!only_eq_ref_tables(join,start_order, (*ref_item)->used_tables())) @@ -8198,7 +8200,8 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, else { DBUG_ASSERT(cond->type() == Item::COND_ITEM); - ((Item_cond *) cond)->add_at_head(&eq_list); + if (eq_list.elements) + ((Item_cond *) cond)->add_at_head(&eq_list); } cond->quick_fix_field(); @@ -9822,7 +9825,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, KEY_PART_INFO *key_part_info; Item **copy_func; MI_COLUMNDEF *recinfo; - uint total_uneven_bit_length= 0; + /* + total_uneven_bit_length is uneven bit length for visible fields + hidden_uneven_bit_length is uneven bit length for hidden fields + */ + uint total_uneven_bit_length= 0, hidden_uneven_bit_length= 0; bool force_copy_fields= param->force_copy_fields; /* Treat sum functions as normal ones when loose index scan is used. */ save_sum_fields|= param->precomputed_group_by; @@ -10099,6 +10106,14 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, */ param->hidden_field_count= fieldnr; null_count= 0; + /* + On last hidden field we store uneven bit length in + hidden_uneven_bit_length and proceed calculation of + uneven bits for visible fields into + total_uneven_bit_length variable. + */ + hidden_uneven_bit_length= total_uneven_bit_length; + total_uneven_bit_length= 0; } } DBUG_ASSERT(fieldnr == (uint) (reg_field - table->field)); @@ -10144,7 +10159,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, else null_count++; } - hidden_null_pack_length=(hidden_null_count+7)/8; + hidden_null_pack_length= (hidden_null_count + 7 + + hidden_uneven_bit_length) / 8; null_pack_length= (hidden_null_pack_length + (null_count + total_uneven_bit_length + 7) / 8); reclength+=null_pack_length; @@ -12896,12 +12912,35 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, uint find_shortest_key(TABLE *table, const key_map *usable_keys) { - uint min_length= (uint) ~0; uint best= MAX_KEY; + uint usable_clustered_pk= (table->file->primary_key_is_clustered() && + table->s->primary_key != MAX_KEY && + usable_keys->is_set(table->s->primary_key)) ? + table->s->primary_key : MAX_KEY; if (!usable_keys->is_clear_all()) { + uint min_length= (uint) ~0; for (uint nr=0; nr < table->s->keys ; nr++) { + /* + As far as + 1) clustered primary key entry data set is a set of all record + fields (key fields and not key fields) and + 2) secondary index entry data is a union of its key fields and + primary key fields (at least InnoDB and its derivatives don't + duplicate primary key fields there, even if the primary and + the secondary keys have a common subset of key fields), + then secondary index entry data is always a subset of primary key + entry, and the PK is always longer. + Unfortunately, key_info[nr].key_length doesn't show the length + of key/pointer pair but a sum of key field lengths only, thus + we can't estimate index IO volume comparing only this key_length + value of seconday keys and clustered PK. + So, try secondary keys first, and choose PK only if there are no + usable secondary covering keys: + */ + if (nr == usable_clustered_pk) + continue; if (usable_keys->is_set(nr)) { if (table->key_info[nr].key_length < min_length) @@ -12912,7 +12951,7 @@ uint find_shortest_key(TABLE *table, const key_map *usable_keys) } } } - return best; + return best != MAX_KEY ? best : usable_clustered_pk; } /** @@ -13291,12 +13330,6 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, */ if (select_limit >= table_records) { - /* - filesort() and join cache are usually faster than reading in - index order and not using join cache - */ - if (tab->type == JT_ALL && tab->join->tables > tab->join->const_tables + 1) - DBUG_RETURN(0); keys= *table->file->keys_to_use_for_scanning(); keys.merge(table->covering_keys); @@ -13446,6 +13479,19 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, } } } + + /* + filesort() and join cache are usually faster than reading in + index order and not using join cache, except in case that chosen + index is clustered primary key. + */ + if ((select_limit >= table_records) && + (tab->type == JT_ALL && + tab->join->tables > tab->join->const_tables + 1) && + ((unsigned) best_key != table->s->primary_key || + !table->file->primary_key_is_clustered())) + DBUG_RETURN(0); + if (best_key >= 0) { bool quick_created= FALSE; @@ -15642,7 +15688,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab) Item_cond_and *cond=new Item_cond_and(); TABLE *table=join_tab->table; - int error; + int error= 0; if (!cond) DBUG_RETURN(TRUE); @@ -15660,7 +15706,8 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab) cond->fix_fields(thd, (Item**)&cond); if (join_tab->select) { - error=(int) cond->add(join_tab->select->cond); + if (join_tab->select->cond) + error=(int) cond->add(join_tab->select->cond); join_tab->select_cond=join_tab->select->cond=cond; } else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0, diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 301ab6ceda6..eb88b1e70a5 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -22,6 +22,7 @@ #include "sp_head.h" #include "sql_trigger.h" #include "sql_show.h" +#include "debug_sync.h" #ifdef __WIN__ #include <io.h> @@ -1889,22 +1890,10 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, pthread_mutex_lock(&LOCK_open); - /* - If we have the table in the definition cache, we don't have to check the - .frm file to find if the table is a normal table (not view) and what - engine to use. - */ - + /* Disable drop of enabled log tables, must be done before name locking */ for (table= tables; table; table= table->next_local) { - TABLE_SHARE *share; - table->db_type= NULL; - if ((share= get_cached_table_share(table->db, table->table_name))) - table->db_type= share->db_type(); - - /* Disable drop of enabled log tables */ - if (share && (share->table_category == TABLE_CATEGORY_PERFORMANCE) && - check_if_log_table(table->db_length, table->db, + if (check_if_log_table(table->db_length, table->db, table->table_name_length, table->table_name, 1)) { my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP"); @@ -1923,7 +1912,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, { char *db=table->db; handlerton *table_type; - enum legacy_db_type frm_db_type; + enum legacy_db_type frm_db_type= DB_TYPE_UNKNOWN; DBUG_PRINT("table", ("table_l: '%s'.'%s' table: 0x%lx s: 0x%lx", table->db, table->table_name, (long) table->table, @@ -1988,7 +1977,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, built_query.append("`,"); } - table_type= table->db_type; if (!drop_temporary) { TABLE *locked_table; @@ -2015,9 +2003,9 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, table->internal_tmp_table ? FN_IS_TMP : 0); } + DEBUG_SYNC(thd, "rm_table_part2_before_delete_table"); if (drop_temporary || - ((table_type == NULL && - access(path, F_OK) && + ((access(path, F_OK) && ha_create_table_from_engine(thd, db, alias)) || (!drop_view && mysql_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE))) @@ -2033,15 +2021,25 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, else { char *end; - if (table_type == NULL) + /* + Cannot use the db_type from the table, since that might have changed + while waiting for the exclusive name lock. We are under LOCK_open, + so reading from the frm-file is safe. + */ + if (frm_db_type == DB_TYPE_UNKNOWN) { - mysql_frm_type(thd, path, &frm_db_type); - table_type= ha_resolve_by_legacy_type(thd, frm_db_type); + mysql_frm_type(thd, path, &frm_db_type); + DBUG_PRINT("info", ("frm_db_type %d from %s", frm_db_type, path)); } + table_type= ha_resolve_by_legacy_type(thd, frm_db_type); // Remove extension for delete *(end= path + path_length - reg_ext_length)= '\0'; + DBUG_PRINT("info", ("deleting table of type %d", + (table_type ? table_type->db_type : 0))); error= ha_delete_table(thd, table_type, path, db, table->table_name, !dont_log_query); + + /* No error if non existent table and 'IF EXIST' clause or view */ if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && (if_exists || table_type == NULL)) { @@ -2081,6 +2079,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, on the table name. */ pthread_mutex_unlock(&LOCK_open); + DEBUG_SYNC(thd, "rm_table_part2_before_binlog"); thd->thread_specific_used|= tmp_table_deleted; error= 0; if (wrong_tables.length()) @@ -7120,6 +7119,7 @@ view_err: else create_info->data_file_name=create_info->index_file_name=0; + DEBUG_SYNC(thd, "alter_table_before_create_table_no_lock"); /* Create a table with a temporary name. With create_info->frm_only == 1 this creates a .frm file only. @@ -7320,6 +7320,7 @@ view_err: intern_close_table(new_table); my_free(new_table,MYF(0)); } + DEBUG_SYNC(thd, "alter_table_before_rename_result_table"); VOID(pthread_mutex_lock(&LOCK_open)); if (error) { @@ -7462,6 +7463,7 @@ view_err: thd_proc_info(thd, "end"); DBUG_EXECUTE_IF("sleep_alter_before_main_binlog", my_sleep(6000000);); + DEBUG_SYNC(thd, "alter_table_before_main_binlog"); ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE, thd->query(), thd->query_length(), @@ -7932,22 +7934,28 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, for (uint i= 0; i < t->s->fields; i++ ) { Field *f= t->field[i]; - enum_field_types field_type= f->type(); - /* - BLOB and VARCHAR have pointers in their field, we must convert - to string; GEOMETRY is implemented on top of BLOB. - */ - if ((field_type == MYSQL_TYPE_BLOB) || - (field_type == MYSQL_TYPE_VARCHAR) || - (field_type == MYSQL_TYPE_GEOMETRY)) - { - String tmp; - f->val_str(&tmp); - row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(), tmp.length()); + + /* + BLOB and VARCHAR have pointers in their field, we must convert + to string; GEOMETRY is implemented on top of BLOB. + BIT may store its data among NULL bits, convert as well. + */ + switch (f->type()) { + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_VARCHAR: + case MYSQL_TYPE_GEOMETRY: + case MYSQL_TYPE_BIT: + { + String tmp; + f->val_str(&tmp); + row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(), + tmp.length()); + break; + } + default: + row_crc= my_checksum(row_crc, f->ptr, f->pack_length()); + break; } - else - row_crc= my_checksum(row_crc, f->ptr, - f->pack_length()); } crc+= row_crc; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 84610630d62..63af275cef3 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1283,7 +1283,8 @@ bool mysql_multi_update(THD *thd, if (using_handler) { - Internal_error_handler *top_handler= thd->pop_internal_handler(); + Internal_error_handler *top_handler; + top_handler= thd->pop_internal_handler(); DBUG_ASSERT(&handler == top_handler); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 37150bf835d..8dc08f8425f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4596,7 +4596,7 @@ create_table_option: | TYPE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; - WARN_DEPRECATED(yythd, "5.4.4", "TYPE=storage_engine", + WARN_DEPRECATED(yythd, "6.0", "TYPE=storage_engine", "'ENGINE=storage_engine'"); Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE; } diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index ca9d5215310..e3bc7f55dd2 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -679,9 +679,21 @@ int ha_tina::find_current_row(uchar *buf) if (read_all || bitmap_is_set(table->read_set, (*field)->field_index)) { + bool is_enum= ((*field)->real_type() == MYSQL_TYPE_ENUM); + /* + Here CHECK_FIELD_WARN checks that all values in the csv file are valid + which is normally the case, if they were written by + INSERT -> ha_tina::write_row. '0' values on ENUM fields are considered + invalid by Field_enum::store() but it can store them on INSERT anyway. + Thus, for enums we silence the warning, as it doesn't really mean + an invalid value. + */ if ((*field)->store(buffer.ptr(), buffer.length(), buffer.charset(), - CHECK_FIELD_WARN)) - goto err; + is_enum ? CHECK_FIELD_IGNORE : CHECK_FIELD_WARN)) + { + if (!is_enum) + goto err; + } if ((*field)->flags & BLOB_FLAG) { Field_blob *blob= *(Field_blob**) field; diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index 8deb8693960..f8dde34b82b 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -1621,11 +1621,10 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked) DBUG_ASSERT(mysql == NULL); - ref_length= (table->s->primary_key != MAX_KEY ? - table->key_info[table->s->primary_key].key_length : - table->s->reclength); + ref_length= sizeof(MYSQL_RES *) + sizeof(MYSQL_ROW_OFFSET); DBUG_PRINT("info", ("ref_length: %u", ref_length)); + my_init_dynamic_array(&results, sizeof(MYSQL_RES *), 4, 4); reset(); DBUG_RETURN(0); @@ -1645,21 +1644,17 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked) int ha_federated::close(void) { - int retval; DBUG_ENTER("ha_federated::close"); - /* free the result set */ - if (stored_result) - { - mysql_free_result(stored_result); - stored_result= 0; - } + free_result(); + + delete_dynamic(&results); + /* Disconnect from mysql */ mysql_close(mysql); mysql= NULL; - retval= free_share(share); - DBUG_RETURN(retval); + DBUG_RETURN(free_share(share)); } /* @@ -2326,8 +2321,7 @@ int ha_federated::index_read(uchar *buf, const uchar *key, { DBUG_ENTER("ha_federated::index_read"); - if (stored_result) - mysql_free_result(stored_result); + free_result(); DBUG_RETURN(index_read_idx_with_result_set(buf, active_index, key, key_len, find_flag, &stored_result)); @@ -2359,7 +2353,8 @@ int ha_federated::index_read_idx(uchar *buf, uint index, const uchar *key, &mysql_result))) DBUG_RETURN(retval); mysql_free_result(mysql_result); - DBUG_RETURN(retval); + results.elements--; + DBUG_RETURN(0); } @@ -2415,18 +2410,20 @@ int ha_federated::index_read_idx_with_result_set(uchar *buf, uint index, retval= ER_QUERY_ON_FOREIGN_DATA_SOURCE; goto error; } - if (!(*result= mysql_store_result(mysql))) + if (!(*result= store_result(mysql))) { retval= HA_ERR_END_OF_FILE; goto error; } - if (!(retval= read_next(buf, *result))) + if ((retval= read_next(buf, *result))) + { + mysql_free_result(*result); + results.elements--; + *result= 0; + table->status= STATUS_NOT_FOUND; DBUG_RETURN(retval); - - mysql_free_result(*result); - *result= 0; - table->status= STATUS_NOT_FOUND; - DBUG_RETURN(retval); + } + DBUG_RETURN(0); error: table->status= STATUS_NOT_FOUND; @@ -2486,12 +2483,6 @@ int ha_federated::read_range_first(const key_range *start_key, create_where_from_key(&sql_query, &table->key_info[active_index], start_key, end_key, 0, eq_range_arg); - - if (stored_result) - { - mysql_free_result(stored_result); - stored_result= 0; - } if (real_query(sql_query.ptr(), sql_query.length())) { retval= ER_QUERY_ON_FOREIGN_DATA_SOURCE; @@ -2499,14 +2490,13 @@ int ha_federated::read_range_first(const key_range *start_key, } sql_query.length(0); - if (!(stored_result= mysql_store_result(mysql))) + if (!(stored_result= store_result(mysql))) { retval= HA_ERR_END_OF_FILE; goto error; } - - retval= read_next(table->record[0], stored_result); - DBUG_RETURN(retval); + + DBUG_RETURN(read_next(table->record[0], stored_result)); error: table->status= STATUS_NOT_FOUND; @@ -2516,10 +2506,8 @@ error: int ha_federated::read_range_next() { - int retval; DBUG_ENTER("ha_federated::read_range_next"); - retval= rnd_next(table->record[0]); - DBUG_RETURN(retval); + DBUG_RETURN(rnd_next(table->record[0])); } @@ -2585,23 +2573,11 @@ int ha_federated::rnd_init(bool scan) if (scan) { - if (stored_result) - { - mysql_free_result(stored_result); - stored_result= 0; - } - - if (real_query(share->select_query, strlen(share->select_query))) - goto error; - - stored_result= mysql_store_result(mysql); - if (!stored_result) - goto error; + if (real_query(share->select_query, strlen(share->select_query)) || + !(stored_result= store_result(mysql))) + DBUG_RETURN(stash_remote_error()); } DBUG_RETURN(0); - -error: - DBUG_RETURN(stash_remote_error()); } @@ -2615,11 +2591,7 @@ int ha_federated::rnd_end() int ha_federated::index_end(void) { DBUG_ENTER("ha_federated::index_end"); - if (stored_result) - { - mysql_free_result(stored_result); - stored_result= 0; - } + free_result(); active_index= MAX_KEY; DBUG_RETURN(0); } @@ -2679,6 +2651,9 @@ int ha_federated::read_next(uchar *buf, MYSQL_RES *result) DBUG_ENTER("ha_federated::read_next"); table->status= STATUS_NOT_FOUND; // For easier return + + /* Save current data cursor position. */ + current_position= result->data_cursor; /* Fetch a row, insert it back in a row format. */ if (!(row= mysql_fetch_row(result))) @@ -2691,24 +2666,38 @@ int ha_federated::read_next(uchar *buf, MYSQL_RES *result) } -/* - store reference to current row so that we can later find it for - a re-read, update or delete. - - In case of federated, a reference is either a primary key or - the whole record. - - Called from filesort.cc, sql_select.cc, sql_delete.cc and sql_update.cc. +/** + @brief Store a reference to current row. + + @details During a query execution we may have different result sets (RS), + e.g. for different ranges. All the RS's used are stored in + memory and placed in @c results dynamic array. At the end of + execution all stored RS's are freed at once in the + @c ha_federated::reset(). + So, in case of federated, a reference to current row is a + stored result address and current data cursor position. + As we keep all RS in memory during a query execution, + we can get any record using the reference any time until + @c ha_federated::reset() is called. + TODO: we don't have to store all RS's rows but only those + we call @c ha_federated::position() for, so we can free memory + where we store other rows in the @c ha_federated::index_end(). + + @param[in] record record data (unused) */ -void ha_federated::position(const uchar *record) +void ha_federated::position(const uchar *record __attribute__ ((unused))) { DBUG_ENTER("ha_federated::position"); - if (table->s->primary_key != MAX_KEY) - key_copy(ref, (uchar *)record, table->key_info + table->s->primary_key, - ref_length); - else - memcpy(ref, record, ref_length); + + DBUG_ASSERT(stored_result); + + position_called= TRUE; + /* Store result set address. */ + memcpy_fixed(ref, &stored_result, sizeof(MYSQL_RES *)); + /* Store data cursor position. */ + memcpy_fixed(ref + sizeof(MYSQL_RES *), ¤t_position, + sizeof(MYSQL_ROW_OFFSET)); DBUG_VOID_RETURN; } @@ -2724,23 +2713,19 @@ void ha_federated::position(const uchar *record) int ha_federated::rnd_pos(uchar *buf, uchar *pos) { - int result; + MYSQL_RES *result; DBUG_ENTER("ha_federated::rnd_pos"); + ha_statistic_increment(&SSV::ha_read_rnd_count); - if (table->s->primary_key != MAX_KEY) - { - /* We have a primary key, so use index_read_idx to find row */ - result= index_read_idx(buf, table->s->primary_key, pos, - ref_length, HA_READ_KEY_EXACT); - } - else - { - /* otherwise, get the old record ref as obtained in ::position */ - memcpy(buf, pos, ref_length); - result= 0; - } - table->status= result ? STATUS_NOT_FOUND : 0; - DBUG_RETURN(result); + + /* Get stored result set. */ + memcpy_fixed(&result, pos, sizeof(MYSQL_RES *)); + DBUG_ASSERT(result); + /* Set data cursor position. */ + memcpy_fixed(&result->data_cursor, pos + sizeof(MYSQL_RES *), + sizeof(MYSQL_ROW_OFFSET)); + /* Read a row. */ + DBUG_RETURN(read_next(buf, result)); } @@ -2943,6 +2928,16 @@ int ha_federated::reset(void) insert_dup_update= FALSE; ignore_duplicates= FALSE; replace_duplicates= FALSE; + + /* Free stored result sets. */ + for (uint i= 0; i < results.elements; i++) + { + MYSQL_RES *result; + get_dynamic(&results, (uchar *) &result, i); + mysql_free_result(result); + } + reset_dynamic(&results); + return 0; } @@ -3206,6 +3201,45 @@ bool ha_federated::get_error_message(int error, String* buf) DBUG_RETURN(FALSE); } + +/** + @brief Store a result set. + + @details Call @c mysql_store_result() to save a result set then + append it to the stored results array. + + @param[in] mysql MySLQ connection structure. + + @return Stored result set (MYSQL_RES object). +*/ + +MYSQL_RES *ha_federated::store_result(MYSQL *mysql) +{ + MYSQL_RES *result= mysql_store_result(mysql); + DBUG_ENTER("ha_federated::store_result"); + if (result) + { + (void) insert_dynamic(&results, (uchar*) &result); + } + position_called= FALSE; + DBUG_RETURN(result); +} + + +void ha_federated::free_result() +{ + DBUG_ENTER("ha_federated::free_result"); + if (stored_result && !position_called) + { + mysql_free_result(stored_result); + stored_result= 0; + if (results.elements > 0) + results.elements--; + } + DBUG_VOID_RETURN; +} + + int ha_federated::external_lock(THD *thd, int lock_type) { int error= 0; diff --git a/storage/federated/ha_federated.h b/storage/federated/ha_federated.h index 2f1c62decca..2e0a19e592f 100644 --- a/storage/federated/ha_federated.h +++ b/storage/federated/ha_federated.h @@ -84,6 +84,11 @@ class ha_federated: public handler FEDERATED_SHARE *share; /* Shared lock info */ MYSQL *mysql; /* MySQL connection */ MYSQL_RES *stored_result; + /** + Array of all stored results we get during a query execution. + */ + DYNAMIC_ARRAY results; + bool position_called; uint fetch_num; // stores the fetch num MYSQL_ROW_OFFSET current_position; // Current position used by ::position() int remote_error_number; @@ -251,6 +256,10 @@ public: THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type); //required bool get_error_message(int error, String *buf); + + MYSQL_RES *store_result(MYSQL *mysql); + void free_result(); + int external_lock(THD *thd, int lock_type); int connection_commit(); int connection_rollback(); diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index 901ce8e0fef..45867388a61 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -224,6 +224,9 @@ in the free list to the frames. /* Value in microseconds */ static const int WAIT_FOR_READ = 20000; +/* Number of attemtps made to read in a page in the buffer pool */ +static const ulint BUF_PAGE_READ_MAX_RETRIES = 100; + buf_pool_t* buf_pool = NULL; /* The buffer buf_pool of the database */ #ifdef UNIV_DEBUG @@ -1160,6 +1163,7 @@ buf_page_get_gen( ulint fix_type; ibool success; ibool must_read; + ulint retries = 0; ut_ad(mtr); ut_ad((rw_latch == RW_S_LATCH) @@ -1200,7 +1204,29 @@ loop: return(NULL); } - buf_read_page(space, offset); + if (buf_read_page(space, offset)) { + retries = 0; + } else if (retries < BUF_PAGE_READ_MAX_RETRIES) { + ++retries; + } else { + fprintf(stderr, "InnoDB: Error: Unable" + " to read tablespace %lu page no" + " %lu into the buffer pool after" + " %lu attempts\n" + "InnoDB: The most probable cause" + " of this error may be that the" + " table has been corrupted.\n" + "InnoDB: You can try to fix this" + " problem by using" + " innodb_force_recovery.\n" + "InnoDB: Please see reference manual" + " for more details.\n" + "InnoDB: Aborting...\n", + space, offset, + BUF_PAGE_READ_MAX_RETRIES); + + ut_error; + } #ifdef UNIV_DEBUG buf_dbg_counter++; diff --git a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c index fdec0206990..451436ef75b 100644 --- a/storage/innobase/buf/buf0rea.c +++ b/storage/innobase/buf/buf0rea.c @@ -299,30 +299,27 @@ buffer buf_pool if it is not already there. Sets the io_fix flag and sets an exclusive lock on the buffer frame. The flag is cleared and the x-lock released by the i/o-handler thread. Does a random read-ahead if it seems sensible. */ - -ulint +ibool buf_read_page( /*==========*/ - /* out: number of page read requests issued: this can - be > 1 if read-ahead occurred */ + /* out: TRUE if success, FALSE otherwise */ ulint space, /* in: space id */ ulint offset) /* in: page number */ { ib_longlong tablespace_version; ulint count; - ulint count2; ulint err; tablespace_version = fil_space_get_version(space); - count = buf_read_ahead_random(space, offset); + buf_read_ahead_random(space, offset); /* We do the i/o in the synchronous aio mode to save thread switches: hence TRUE */ - count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space, + count = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space, tablespace_version, offset); - srv_buf_pool_reads+= count2; + srv_buf_pool_reads+= count; if (err == DB_TABLESPACE_DELETED) { ut_print_timestamp(stderr); fprintf(stderr, @@ -336,7 +333,7 @@ buf_read_page( /* Flush pages from the end of the LRU list if necessary */ buf_flush_free_margin(); - return(count + count2); + return(count > 0); } /************************************************************************ diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 9b6c2cf9895..b037fa0d0fd 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2652,9 +2652,9 @@ ha_innobase::innobase_initialize_autoinc() auto_inc = innobase_get_int_col_max_value(field); } else { /* We have no idea what's been passed in to us as the - autoinc column. We set it to the MAX_INT of our table - autoinc type. */ - auto_inc = 0xFFFFFFFFFFFFFFFFULL; + autoinc column. We set it to the 0, effectively disabling + updates to the table. */ + auto_inc = 0; ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Unable to determine the AUTOINC " @@ -2663,7 +2663,7 @@ ha_innobase::innobase_initialize_autoinc() if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { /* If the recovery level is set so high that writes - are disabled we force the AUTOINC counter to the MAX + are disabled we force the AUTOINC counter to 0 value effectively disabling writes to the table. Secondly, we avoid reading the table in case the read results in failure due to a corrupted table/index. @@ -2672,7 +2672,10 @@ ha_innobase::innobase_initialize_autoinc() tables can be dumped with minimal hassle. If an error were returned in this case, the first attempt to read the table would fail and subsequent SELECTs would succeed. */ + auto_inc = 0; } else if (field == NULL) { + /* This is a far more serious error, best to avoid + opening the table and return failure. */ my_error(ER_AUTOINC_READ_FAILED, MYF(0)); } else { dict_index_t* index; @@ -2701,7 +2704,7 @@ ha_innobase::innobase_initialize_autoinc() "InnoDB: Unable to find the AUTOINC column " "%s in the InnoDB table %s.\n" "InnoDB: We set the next AUTOINC column " - "value to the maximum possible value,\n" + "value to 0,\n" "InnoDB: in effect disabling the AUTOINC " "next value generation.\n" "InnoDB: You can either set the next " @@ -2710,7 +2713,13 @@ ha_innobase::innobase_initialize_autoinc() "recreating the table.\n", col_name, index->table->name); - my_error(ER_AUTOINC_READ_FAILED, MYF(0)); + /* This will disable the AUTOINC generation. */ + auto_inc = 0; + + /* We want the open to succeed, so that the user can + take corrective action. ie. reads should succeed but + updates should fail. */ + err = DB_SUCCESS; break; default: /* row_search_max_autoinc() should only return @@ -3968,11 +3977,17 @@ no_commit: prebuilt->autoinc_error = DB_SUCCESS; if ((error = update_auto_increment())) { - /* We don't want to mask autoinc overflow errors. */ - if (prebuilt->autoinc_error != DB_SUCCESS) { - error = (int) prebuilt->autoinc_error; + /* Handle the case where the AUTOINC sub-system + failed during initialization. */ + if (prebuilt->autoinc_error == DB_UNSUPPORTED) { + error_result = ER_AUTOINC_READ_FAILED; + /* Set the error message to report too. */ + my_error(ER_AUTOINC_READ_FAILED, MYF(0)); + goto func_exit; + } else if (prebuilt->autoinc_error != DB_SUCCESS) { + error = (int) prebuilt->autoinc_error; goto report_error; } @@ -7883,7 +7898,10 @@ ha_innobase::innobase_get_autoinc( *value = dict_table_autoinc_read(prebuilt->table); /* It should have been initialized during open. */ - ut_a(*value != 0); + if (*value == 0) { + prebuilt->autoinc_error = DB_UNSUPPORTED; + dict_table_autoinc_unlock(prebuilt->table); + } } return(ulong(prebuilt->autoinc_error)); @@ -7963,6 +7981,11 @@ ha_innobase::get_auto_increment( invoking this method. So we are not sure if it's guaranteed to be 0 or not. */ + /* We need the upper limit of the col type to check for + whether we update the table autoinc counter or not. */ + ulonglong col_max_value = innobase_get_int_col_max_value( + table->next_number_field); + /* Called for the first time ? */ if (trx->n_autoinc_rows == 0) { @@ -7979,6 +8002,11 @@ ha_innobase::get_auto_increment( /* Not in the middle of a mult-row INSERT. */ } else if (prebuilt->autoinc_last_value == 0) { set_if_bigger(*first_value, autoinc); + /* Check for -ve values. */ + } else if (*first_value > col_max_value && trx->n_autoinc_rows > 0) { + /* Set to next logical value. */ + ut_a(autoinc > trx->n_autoinc_rows); + *first_value = (autoinc - trx->n_autoinc_rows) - 1; } *nb_reserved_values = trx->n_autoinc_rows; @@ -7989,12 +8017,6 @@ ha_innobase::get_auto_increment( ulonglong need; ulonglong current; ulonglong next_value; - ulonglong col_max_value; - - /* We need the upper limit of the col type to check for - whether we update the table autoinc counter or not. */ - col_max_value = innobase_get_int_col_max_value( - table->next_number_field); current = *first_value > col_max_value ? autoinc : *first_value; need = *nb_reserved_values * increment; diff --git a/storage/innobase/include/buf0rea.h b/storage/innobase/include/buf0rea.h index e4620172860..015f30fe6c2 100644 --- a/storage/innobase/include/buf0rea.h +++ b/storage/innobase/include/buf0rea.h @@ -18,12 +18,10 @@ buffer buf_pool if it is not already there. Sets the io_fix flag and sets an exclusive lock on the buffer frame. The flag is cleared and the x-lock released by the i/o-handler thread. Does a random read-ahead if it seems sensible. */ - -ulint +ibool buf_read_page( /*==========*/ - /* out: number of page read requests issued: this can - be > 1 if read-ahead occurred */ + /* out: TRUE if success, FALSE otherwise */ ulint space, /* in: space id */ ulint offset);/* in: page number */ /************************************************************************ diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 4cc10931060..8f4b64cda96 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -306,6 +306,7 @@ FILE* lock_latest_err_file; /* Flags for recursive deadlock search */ #define LOCK_VICTIM_IS_START 1 #define LOCK_VICTIM_IS_OTHER 2 +#define LOCK_EXCEED_MAX_DEPTH 3 /************************************************************************ Checks if a lock request results in a deadlock. */ @@ -332,16 +333,18 @@ lock_deadlock_recursive( was found and we chose some other trx as a victim: we must do the search again in this last case because there may be another - deadlock! */ + deadlock! + LOCK_EXCEED_MAX_DEPTH if the lock search + exceeds max steps and/or max depth. */ trx_t* start, /* in: recursion starting point */ trx_t* trx, /* in: a transaction waiting for a lock */ lock_t* wait_lock, /* in: the lock trx is waiting to be granted */ ulint* cost, /* in/out: number of calculation steps thus far: if this exceeds LOCK_MAX_N_STEPS_... - we return LOCK_VICTIM_IS_START */ + we return LOCK_EXCEED_MAX_DEPTH */ ulint depth); /* in: recursion depth: if this exceeds LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we - return LOCK_VICTIM_IS_START */ + return LOCK_EXCEED_MAX_DEPTH */ /************************************************************************* Gets the nth bit of a record lock. */ @@ -3084,8 +3087,6 @@ lock_deadlock_occurs( lock_t* lock, /* in: lock the transaction is requesting */ trx_t* trx) /* in: transaction */ { - dict_table_t* table; - dict_index_t* index; trx_t* mark_trx; ulint ret; ulint cost = 0; @@ -3107,31 +3108,50 @@ retry: ret = lock_deadlock_recursive(trx, trx, lock, &cost, 0); - if (ret == LOCK_VICTIM_IS_OTHER) { + switch (ret) { + case LOCK_VICTIM_IS_OTHER: /* We chose some other trx as a victim: retry if there still is a deadlock */ - goto retry; - } - if (ret == LOCK_VICTIM_IS_START) { - if (lock_get_type(lock) & LOCK_TABLE) { - table = lock->un_member.tab_lock.table; - index = NULL; + case LOCK_EXCEED_MAX_DEPTH: + /* If the lock search exceeds the max step + or the max depth, the current trx will be + the victim. Print its information. */ + rewind(lock_latest_err_file); + ut_print_timestamp(lock_latest_err_file); + + fputs("TOO DEEP OR LONG SEARCH IN THE LOCK TABLE" + " WAITS-FOR GRAPH, WE WILL ROLL BACK" + " FOLLOWING TRANSACTION \n", + lock_latest_err_file); + + fputs("\n*** TRANSACTION:\n", lock_latest_err_file); + trx_print(lock_latest_err_file, trx, 3000); + + fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n", + lock_latest_err_file); + + if (lock_get_type(lock) == LOCK_REC) { + lock_rec_print(lock_latest_err_file, lock); } else { - index = lock->index; - table = index->table; + lock_table_print(lock_latest_err_file, lock); } + break; - lock_deadlock_found = TRUE; - + case LOCK_VICTIM_IS_START: fputs("*** WE ROLL BACK TRANSACTION (2)\n", lock_latest_err_file); + break; - return(TRUE); + default: + /* No deadlock detected*/ + return(FALSE); } - return(FALSE); + lock_deadlock_found = TRUE; + + return(TRUE); } /************************************************************************ @@ -3147,16 +3167,18 @@ lock_deadlock_recursive( was found and we chose some other trx as a victim: we must do the search again in this last case because there may be another - deadlock! */ + deadlock! + LOCK_EXCEED_MAX_DEPTH if the lock search + exceeds max steps and/or max depth. */ trx_t* start, /* in: recursion starting point */ trx_t* trx, /* in: a transaction waiting for a lock */ lock_t* wait_lock, /* in: the lock trx is waiting to be granted */ ulint* cost, /* in/out: number of calculation steps thus far: if this exceeds LOCK_MAX_N_STEPS_... - we return LOCK_VICTIM_IS_START */ + we return LOCK_EXCEED_MAX_DEPTH */ ulint depth) /* in: recursion depth: if this exceeds LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we - return LOCK_VICTIM_IS_START */ + return LOCK_EXCEED_MAX_DEPTH */ { lock_t* lock; ulint bit_no = ULINT_UNDEFINED; @@ -3215,7 +3237,7 @@ lock_deadlock_recursive( lock_trx = lock->trx; - if (lock_trx == start || too_far) { + if (lock_trx == start) { /* We came back to the recursion starting point: a deadlock detected; or we have @@ -3262,19 +3284,10 @@ lock_deadlock_recursive( } #ifdef UNIV_DEBUG if (lock_print_waits) { - fputs("Deadlock detected" - " or too long search\n", + fputs("Deadlock detected\n", stderr); } #endif /* UNIV_DEBUG */ - if (too_far) { - - fputs("TOO DEEP OR LONG SEARCH" - " IN THE LOCK TABLE" - " WAITS-FOR GRAPH\n", ef); - - return(LOCK_VICTIM_IS_START); - } if (trx_weight_cmp(wait_lock->trx, start) >= 0) { @@ -3310,6 +3323,21 @@ lock_deadlock_recursive( return(LOCK_VICTIM_IS_OTHER); } + if (too_far) { + +#ifdef UNIV_DEBUG + if (lock_print_waits) { + fputs("Deadlock search exceeds" + " max steps or depth.\n", + stderr); + } +#endif /* UNIV_DEBUG */ + /* The information about transaction/lock + to be rolled back is available in the top + level. Do not print anything here. */ + return(LOCK_EXCEED_MAX_DEPTH); + } + if (lock_trx->que_state == TRX_QUE_LOCK_WAIT) { /* Another trx ahead has requested lock in an diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index 085f62daacc..7373a97cfb0 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -759,7 +759,15 @@ next_file: #ifdef HAVE_READDIR_R ret = readdir_r(dir, (struct dirent*)dirent_buf, &ent); - if (ret != 0) { + if (ret != 0 +#ifdef UNIV_AIX + /* On AIX, only if we got non-NULL 'ent' (result) value and + a non-zero 'ret' (return) value, it indicates a failed + readdir_r() call. An NULL 'ent' with an non-zero 'ret' + would indicate the "end of the directory" is reached. */ + && ent != NULL +#endif + ) { fprintf(stderr, "InnoDB: cannot read directory %s, error %lu\n", dirname, (ulong)ret); diff --git a/storage/myisam/rt_index.c b/storage/myisam/rt_index.c index e094c302f92..31241a83228 100644 --- a/storage/myisam/rt_index.c +++ b/storage/myisam/rt_index.c @@ -404,10 +404,16 @@ int rtree_get_first(MI_INFO *info, uint keynr, uint key_length) int rtree_get_next(MI_INFO *info, uint keynr, uint key_length) { - my_off_t root; + my_off_t root= info->s->state.key_root[keynr]; MI_KEYDEF *keyinfo = info->s->keyinfo + keynr; - if (!info->buff_used) + if (root == HA_OFFSET_ERROR) + { + my_errno= HA_ERR_END_OF_FILE; + return -1; + } + + if (!info->buff_used && !info->page_changed) { uint k_len = keyinfo->keylength - info->s->base.rec_reflength; /* rt_PAGE_NEXT_KEY(info->int_keypos) */ @@ -428,16 +434,8 @@ int rtree_get_next(MI_INFO *info, uint keynr, uint key_length) return 0; } - else - { - if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR) - { - my_errno= HA_ERR_END_OF_FILE; - return -1; - } - - return rtree_get_req(info, keyinfo, key_length, root, 0); - } + + return rtree_get_req(info, keyinfo, key_length, root, 0); } diff --git a/storage/ndb/src/common/util/Makefile.am b/storage/ndb/src/common/util/Makefile.am index 5379a425c49..5cf02fed12f 100644 --- a/storage/ndb/src/common/util/Makefile.am +++ b/storage/ndb/src/common/util/Makefile.am @@ -37,7 +37,7 @@ testBitmask_LDFLAGS = @ndb_bin_am_ldflags@ \ testBitmask.cpp : Bitmask.cpp rm -f testBitmask.cpp - @LN_CP_F@ Bitmask.cpp testBitmask.cpp + @LN_CP_F@ $(srcdir)/Bitmask.cpp testBitmask.cpp testBitmask.o: $(testBitmask_SOURCES) $(CXXCOMPILE) -c $(INCLUDES) -D__TEST_BITMASK__ $< diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 905919f053a..18e55d7a06a 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -535,6 +535,7 @@ fi if expr "$CC" : ".*icc.*" > /dev/null ; then %define WITH_LIBGCC 0 + : elif expr "$CC" : ".*gcc.*" > /dev/null ; then libgcc=`$CC $CFLAGS --print-libgcc-file` @@ -544,9 +545,11 @@ then install -m 644 $libgcc $RBR%{_libdir}/mysql/libmygcc.a else %define WITH_LIBGCC 0 + : fi else %define WITH_LIBGCC 0 + : fi ############################################################################## |