diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 2ef55c23c90..a20db4134c2 100755 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -32,7 +32,8 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c) TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32) -ADD_EXECUTABLE(mysqltest mysqltest.c ../mysys/my_getsystime.c ../mysys/my_copy.c) +ADD_EXECUTABLE(mysqltest mysqltest.c ../mysys/my_getsystime.c + ../mysys/my_copy.c ../mysys/my_mkdir.c) TARGET_LINK_LIBRARIES(mysqltest mysqlclient_notls regex wsock32) ADD_EXECUTABLE(mysqlcheck mysqlcheck.c) diff --git a/client/Makefile.am b/client/Makefile.am index 2d8bd918734..c57a5673367 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -88,7 +88,8 @@ mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ mysqltest_SOURCES= mysqltest.c \ $(top_srcdir)/mysys/my_getsystime.c \ - $(top_srcdir)/mysys/my_copy.c + $(top_srcdir)/mysys/my_copy.c \ + $(top_srcdir)/mysys/my_mkdir.c mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) mysql_upgrade_SOURCES= mysql_upgrade.c \ diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 8b79266d749..8de096e5ec1 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -59,7 +59,8 @@ static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace"; #endif static const char *load_default_groups[]= { "mysqlbinlog","client",0 }; -void sql_print_error(const char *format, ...); +static void error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); +static void warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0; static bool opt_hexdump= 0; @@ -92,24 +93,33 @@ static ulonglong rec_count= 0; static short binlog_flags = 0; static MYSQL* mysql = NULL; static const char* dirname_for_local_load= 0; -static bool stop_passed= 0; -static my_bool file_not_closed_error= 0; -/* - check_header() will set the pointer below. - Why do we need here a pointer on an event instead of an event ? - This is because the event will be created (alloced) in read_log_event() - (which returns a pointer) in check_header(). +/** + Pointer to the Format_description_log_event of the currently active binlog. + + This will be changed each time a new Format_description_log_event is + found in the binlog. It is finally destroyed at program termination. */ -static Format_description_log_event* glob_description_event; +static Format_description_log_event* glob_description_event= NULL; -static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, - const char* logname); -static int dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, - const char* logname); -static int dump_log_entries(const char* logname); -static void die(const char* fmt, ...) __attribute__ ((__noreturn__)); -static MYSQL* safe_connect(); +/** + Exit status for functions in this file. +*/ +enum Exit_status { + /** No error occurred and execution should continue. */ + OK_CONTINUE= 0, + /** An error occurred and execution should stop. */ + ERROR_STOP, + /** No error occurred but execution should stop. */ + OK_STOP +}; + +static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, + const char* logname); +static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, + const char* logname); +static Exit_status dump_log_entries(const char* logname); +static Exit_status safe_connect(); class Load_log_processor @@ -132,22 +142,29 @@ class Load_log_processor char *fname; Create_file_log_event *event; }; + /* + @todo Should be a map (e.g., a hash map), not an array. With the + present implementation, the number of elements in this array is + about the number of files loaded since the server started, which + may be big after a few years. We should be able to use existing + library data structures for this. /Sven + */ DYNAMIC_ARRAY file_names; - /* - Looking for new uniquie filename that doesn't exist yet by - adding postfix -%x + /** + Looks for a non-existing filename by adding a numerical suffix to + the given base name, creates the generated file, and returns the + filename by modifying the filename argument. - SYNOPSIS - create_unique_file() - - filename buffer for filename - file_name_end tail of buffer that should be changed - should point to a memory enough to printf("-%x",..) + @param[in,out] filename Base filename - RETURN VALUES - values less than 0 - can't find new filename - values great or equal 0 - created file with found filename + @param[in,out] file_name_end Pointer to last character of + filename. The numerical suffix will be written to this position. + Note that there must be a least five bytes of allocated memory + after file_name_end. + + @retval -1 Error (can't find new filename). + @retval >=0 Found file. */ File create_unique_file(char *filename, char *file_name_end) { @@ -201,22 +218,20 @@ public: delete_dynamic(&file_names); } - /* - Obtain Create_file event for LOAD DATA statement by its file_id. + /** + Obtain Create_file event for LOAD DATA statement by its file_id + and remove it from this Load_log_processor's list of events. - SYNOPSIS - grab_event() - file_id - file_id identifiying LOAD DATA statement + Checks whether we have already seen a Create_file_log_event with + the given file_id. If yes, returns a pointer to the event and + removes the event from array describing active temporary files. + From this moment, the caller is responsible for freeing the memory + occupied by the event. - DESCRIPTION - Checks whenever we have already seen Create_file event for this file_id. - If yes then returns pointer to it and removes it from array describing - active temporary files. Since this moment caller is responsible for - freeing memory occupied by this event and associated file name. + @param[in] file_id File id identifying LOAD DATA statement. - RETURN VALUES - Pointer to Create_file event or 0 if there was no such event - with this file_id. + @return Pointer to Create_file_log_event, or NULL if we have not + seen any Create_file_log_event with this file_id. */ Create_file_log_event *grab_event(uint file_id) { @@ -231,23 +246,20 @@ public: return res; } - /* - Obtain file name of temporary file for LOAD DATA statement by its file_id. + /** + Obtain file name of temporary file for LOAD DATA statement by its + file_id and remove it from this Load_log_processor's list of events. - SYNOPSIS - grab_fname() - file_id - file_id identifiying LOAD DATA statement + @param[in] file_id Identifier for the LOAD DATA statement. - DESCRIPTION - Checks whenever we have already seen Begin_load_query event for this - file_id. If yes then returns file name of corresponding temporary file. - Removes record about this file from the array of active temporary files. - Since this moment caller is responsible for freeing memory occupied by - this name. + Checks whether we have already seen Begin_load_query event for + this file_id. If yes, returns the file name of the corresponding + temporary file and removes the filename from the array of active + temporary files. From this moment, the caller is responsible for + freeing the memory occupied by this name. - RETURN VALUES - String with name of temporary file or 0 if we have not seen Begin_load_query - event with this file_id. + @return String with the name of the temporary file, or NULL if we + have not seen any Begin_load_query_event with this file_id. */ char *grab_fname(uint file_id) { @@ -264,19 +276,29 @@ public: } return res; } - int process(Create_file_log_event *ce); - int process(Begin_load_query_log_event *ce); - int process(Append_block_log_event *ae); + Exit_status process(Create_file_log_event *ce); + Exit_status process(Begin_load_query_log_event *ce); + Exit_status process(Append_block_log_event *ae); File prepare_new_file_for_old_format(Load_log_event *le, char *filename); - int load_old_format_file(NET* net, const char *server_fname, - uint server_fname_len, File file); - int process_first_event(const char *bname, uint blen, const uchar *block, - uint block_len, uint file_id, - Create_file_log_event *ce); + Exit_status load_old_format_file(NET* net, const char *server_fname, + uint server_fname_len, File file); + Exit_status process_first_event(const char *bname, uint blen, + const uchar *block, + uint block_len, uint file_id, + Create_file_log_event *ce); }; +/** + Creates and opens a new temporary file in the directory specified by previous call to init_by_dir_name() or init_by_cur_dir(). + @param[in] le The basename of the created file will start with the + basename of the file pointed to by this Load_log_event. + + @param[out] filename Buffer to save the filename in. + + @return File handle >= 0 on success, -1 on error. +*/ File Load_log_processor::prepare_new_file_for_old_format(Load_log_event *le, char *filename) { @@ -284,13 +306,13 @@ File Load_log_processor::prepare_new_file_for_old_format(Load_log_event *le, char *tail; File file; - fn_format(filename, le->fname, target_dir_name, "", 1); + fn_format(filename, le->fname, target_dir_name, "", MY_REPLACE_DIR); len= strlen(filename); tail= filename + len; if ((file= create_unique_file(filename,tail)) < 0) { - sql_print_error("Could not construct local filename %s",filename); + error("Could not construct local filename %s.",filename); return -1; } @@ -300,16 +322,33 @@ File Load_log_processor::prepare_new_file_for_old_format(Load_log_event *le, } -int Load_log_processor::load_old_format_file(NET* net, const char*server_fname, - uint server_fname_len, File file) +/** + Reads a file from a server and saves it locally. + + @param[in,out] net The server to read from. + + @param[in] server_fname The name of the file that the server should + read. + + @param[in] server_fname_len The length of server_fname. + + @param[in,out] file The file to write to. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. +*/ +Exit_status Load_log_processor::load_old_format_file(NET* net, + const char*server_fname, + uint server_fname_len, + File file) { uchar buf[FN_REFLEN+1]; buf[0] = 0; memcpy(buf + 1, server_fname, server_fname_len + 1); if (my_net_write(net, buf, server_fname_len +2) || net_flush(net)) { - sql_print_error("Failed requesting the remote dump of %s", server_fname); - return -1; + error("Failed requesting the remote dump of %s.", server_fname); + return ERROR_STOP; } for (;;) @@ -319,8 +358,8 @@ int Load_log_processor::load_old_format_file(NET* net, const char*server_fname, { if (my_net_write(net, (uchar*) "", 0) || net_flush(net)) { - sql_print_error("Failed sending the ack packet"); - return -1; + error("Failed sending the ack packet."); + return ERROR_STOP; } /* we just need to send something, as the server will read but @@ -331,63 +370,63 @@ int Load_log_processor::load_old_format_file(NET* net, const char*server_fname, } else if (packet_len == packet_error) { - sql_print_error("Failed reading a packet during the dump of %s ", - server_fname); - return -1; + error("Failed reading a packet during the dump of %s.", server_fname); + return ERROR_STOP; } if (packet_len > UINT_MAX) { - sql_print_error("Illegal length of packet read from net"); - return -1; + error("Illegal length of packet read from net."); + return ERROR_STOP; } if (my_write(file, (uchar*) net->read_pos, (uint) packet_len, MYF(MY_WME|MY_NABP))) - return -1; + return ERROR_STOP; } - return 0; + return OK_CONTINUE; } -/* - Process first event in the sequence of events representing LOAD DATA - statement. +/** + Process the first event in the sequence of events representing a + LOAD DATA statement. - SYNOPSIS - process_first_event() - bname - base name for temporary file to be created - blen - base name length - block - first block of data to be loaded - block_len - first block length - file_id - identifies LOAD DATA statement - ce - pointer to Create_file event object if we are processing - this type of event. + Creates a temporary file to be used in LOAD DATA and writes first + block of data to it. Registers its file name (and optional + Create_file event) in the array of active temporary files. - DESCRIPTION - Creates temporary file to be used in LOAD DATA and writes first block of - data to it. Registers its file name (and optional Create_file event) - in the array of active temporary files. + @param bname Base name for temporary file to be created. + @param blen Base name length. + @param block First block of data to be loaded. + @param block_len First block length. + @param file_id Identifies the LOAD DATA statement. + @param ce Pointer to Create_file event object if we are processing + this type of event. - RETURN VALUES - 0 - success - non-0 - error + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. */ - -int Load_log_processor::process_first_event(const char *bname, uint blen, - const uchar *block, uint block_len, - uint file_id, - Create_file_log_event *ce) +Exit_status Load_log_processor::process_first_event(const char *bname, + uint blen, + const uchar *block, + uint block_len, + uint file_id, + Create_file_log_event *ce) { uint full_len= target_dir_name_len + blen + 9 + 9 + 1; - int error= 0; + Exit_status retval= OK_CONTINUE; char *fname, *ptr; File file; File_name_record rec; DBUG_ENTER("Load_log_processor::process_first_event"); if (!(fname= (char*) my_malloc(full_len,MYF(MY_WME)))) - DBUG_RETURN(-1); + { + error("Out of memory."); + delete ce; + DBUG_RETURN(ERROR_STOP); + } memcpy(fname, target_dir_name, target_dir_name_len); ptr= fname + target_dir_name_len; @@ -397,9 +436,10 @@ int Load_log_processor::process_first_event(const char *bname, uint blen, if ((file= create_unique_file(fname,ptr)) < 0) { - sql_print_error("Could not construct local filename %s%s", - target_dir_name,bname); - DBUG_RETURN(-1); + error("Could not construct local filename %s%s.", + target_dir_name,bname); + delete ce; + DBUG_RETURN(ERROR_STOP); } rec.fname= fname; @@ -407,23 +447,39 @@ int Load_log_processor::process_first_event(const char *bname, uint blen, if (set_dynamic(&file_names, (uchar*)&rec, file_id)) { - sql_print_error("Could not construct local filename %s%s", - target_dir_name, bname); - DBUG_RETURN(-1); + error("Out of memory."); + delete ce; + DBUG_RETURN(ERROR_STOP); } if (ce) ce->set_fname_outside_temp_buf(fname, strlen(fname)); if (my_write(file, (uchar*)block, block_len, MYF(MY_WME|MY_NABP))) - error= -1; + { + error("Failed writing to file."); + retval= ERROR_STOP; + } if (my_close(file, MYF(MY_WME))) - error= -1; - DBUG_RETURN(error); + { + error("Failed closing file."); + retval= ERROR_STOP; + } + DBUG_RETURN(retval); } -int Load_log_processor::process(Create_file_log_event *ce) +/** + Process the given Create_file_log_event. + + @see Load_log_processor::process_first_event(const char*,uint,const char*,uint,uint,Create_file_log_event*) + + @param ce Create_file_log_event to process. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. +*/ +Exit_status Load_log_processor::process(Create_file_log_event *ce) { const char *bname= ce->fname + dirname_length(ce->fname); uint blen= ce->fname_len - (bname-ce->fname); @@ -433,14 +489,46 @@ int Load_log_processor::process(Create_file_log_event *ce) } -int Load_log_processor::process(Begin_load_query_log_event *blqe) +/** + Process the given Begin_load_query_log_event. + + @see Load_log_processor::process_first_event(const char*,uint,const char*,uint,uint,Create_file_log_event*) + + @param ce Begin_load_query_log_event to process. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. +*/ +Exit_status Load_log_processor::process(Begin_load_query_log_event *blqe) { return process_first_event("SQL_LOAD_MB", 11, blqe->block, blqe->block_len, blqe->file_id, 0); } -int Load_log_processor::process(Append_block_log_event *ae) +/** + Process the given Append_block_log_event. + + Appends the chunk of the file contents specified by the event to the + file created by a previous Begin_load_query_log_event or + Create_file_log_event. + + If the file_id for the event does not correspond to any file + previously registered through a Begin_load_query_log_event or + Create_file_log_event, this member function will print a warning and + return OK_CONTINUE. It is safe to return OK_CONTINUE, because no + query will be written for this event. We should not print an error + and fail, since the missing file_id could be because a (valid) + --start-position has been specified after the Begin/Create event but + before this Append event. + + @param ae Append_block_log_event to process. + + @retval ERROR_STOP An error occurred - the program should terminate. + + @retval OK_CONTINUE No error, the program should continue. +*/ +Exit_status Load_log_processor::process(Append_block_log_event *ae) { DBUG_ENTER("Load_log_processor::process"); const char* fname= ((ae->file_id < file_names.elements) ? @@ -450,15 +538,24 @@ int Load_log_processor::process(Append_block_log_event *ae) if (fname) { File file; - int error= 0; + Exit_status retval= OK_CONTINUE; if (((file= my_open(fname, O_APPEND|O_BINARY|O_WRONLY,MYF(MY_WME))) < 0)) - DBUG_RETURN(-1); + { + error("Failed opening file %s", fname); + DBUG_RETURN(ERROR_STOP); + } if (my_write(file,(uchar*)ae->block,ae->block_len,MYF(MY_WME|MY_NABP))) - error= -1; + { + error("Failed writing to file %s", fname); + retval= ERROR_STOP; + } if (my_close(file,MYF(MY_WME))) - error= -1; - DBUG_RETURN(error); + { + error("Failed closing file %s", fname); + retval= ERROR_STOP; + } + DBUG_RETURN(retval); } /* @@ -466,16 +563,50 @@ int Load_log_processor::process(Append_block_log_event *ae) --start-position). Assuming it's a big --start-position, we just do nothing and print a warning. */ - fprintf(stderr,"Warning: ignoring Append_block as there is no \ -Create_file event for file_id: %u\n",ae->file_id); - DBUG_RETURN(-1); + warning("Ignoring Append_block as there is no " + "Create_file event for file_id: %u", ae->file_id); + DBUG_RETURN(OK_CONTINUE); } -Load_log_processor load_processor; +static Load_log_processor load_processor; -static bool check_database(const char *log_dbname) +/** + Replace windows-style backslashes by forward slashes so it can be + consumed by the mysql client, which requires Unix path. + + @todo This is only useful under windows, so may be ifdef'ed out on + other systems. /Sven + + @todo If a Create_file_log_event contains a filename with a + backslash (valid under unix), then we have problems under windows. + /Sven + + @param[in,out] fname Filename to modify. The filename is modified + in-place. +*/ +static void convert_path_to_forward_slashes(char *fname) +{ + while (*fname) + { + if (*fname == '\\') + *fname= '/'; + fname++; + } +} + + +/** + Indicates whether the given database should be filtered out, + according to the --database=X option. + + @param log_dbname Name of database. + + @return nonzero if the database with the given name should be + filtered out, 0 otherwise. +*/ +static bool shall_skip_database(const char *log_dbname) { return one_database && (log_dbname != NULL) && @@ -483,8 +614,23 @@ static bool check_database(const char *log_dbname) } +/** + Prints the given event in base64 format. -static int + The header is printed to the head cache and the body is printed to + the body cache of the print_event_info structure. This allows all + base64 events corresponding to the same statement to be joined into + one BINLOG statement. + + @param[in] ev Log_event to print. + @param[in,out] result_file FILE to which the output will be written. + @param[in,out] print_event_info Parameters and context state + determining how to print. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. +*/ +static Exit_status write_event_header_and_base64(Log_event *ev, FILE *result_file, PRINT_EVENT_INFO *print_event_info) { @@ -497,35 +643,44 @@ write_event_header_and_base64(Log_event *ev, FILE *result_file, ev->print_base64(body, print_event_info, FALSE); /* Read data from cache and write to result file */ - DBUG_RETURN(copy_event_cache_to_file_and_reinit(head, result_file) || - copy_event_cache_to_file_and_reinit(body, result_file)); + if (copy_event_cache_to_file_and_reinit(head, result_file) || + copy_event_cache_to_file_and_reinit(body, result_file)) + { + error("Error writing event to file."); + DBUG_RETURN(ERROR_STOP); + } + DBUG_RETURN(OK_CONTINUE); } -/* - Process an event +/** + Print the given event, and either delete it or delegate the deletion + to someone else. - SYNOPSIS - process_event() + The deletion may be delegated in two cases: (1) the event is a + Format_description_log_event, and is saved in + glob_description_event; (2) the event is a Create_file_log_event, + and is saved in load_processor. - RETURN - 0 ok and continue - 1 error and terminate - -1 ok and terminate - - TODO - This function returns 0 even in some error cases. This should be changed. + @param[in,out] print_event_info Parameters and context state + determining how to print. + @param[in] ev Log_event to process. + @param[in] pos Offset from beginning of binlog file. + @param[in] logname Name of input binlog. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. + @retval OK_STOP No error, but the end of the specified range of + events to process has been reached and the program should terminate. */ - - - -int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, - my_off_t pos) +Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, + my_off_t pos, const char *logname) { char ll_buff[21]; Log_event_type ev_type= ev->get_type_code(); DBUG_ENTER("process_event"); print_event_info->short_form= short_form; + Exit_status retval= OK_CONTINUE; /* Format events are not concerned by --offset and such, we always need to @@ -545,14 +700,15 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, start_datetime= 0; offset= 0; // print everything and protect against cycling rec_count } - if (server_id && (server_id != ev->server_id)) { - DBUG_RETURN(0); - } + if (server_id && (server_id != ev->server_id)) + /* skip just this event, continue processing the log. */ + goto end; if (((my_time_t)(ev->when) >= stop_datetime) || (pos >= stop_position_mot)) { - stop_passed= 1; // skip all next binlogs - DBUG_RETURN(-1); + /* end the program */ + retval= OK_STOP; + goto end; } if (!short_form) fprintf(result_file, "# at %s\n",llstr(pos,ll_buff)); @@ -568,10 +724,15 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, switch (ev_type) { case QUERY_EVENT: - if (check_database(((Query_log_event*)ev)->db)) + if (shall_skip_database(((Query_log_event*)ev)->db)) goto end; if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) - write_event_header_and_base64(ev, result_file, print_event_info); + { + if ((retval= write_event_header_and_base64(ev, result_file, + print_event_info)) != + OK_CONTINUE) + goto end; + } else ev->print(result_file, print_event_info); break; @@ -585,7 +746,7 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, related Append_block and Exec_load. Note that Load event from 3.23 is not tested. */ - if (check_database(ce->db)) + if (shall_skip_database(ce->db)) goto end; // Next event /* We print the event, but with a leading '#': this is just to inform @@ -596,7 +757,10 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, */ if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) { - write_event_header_and_base64(ce, result_file, print_event_info); + if ((retval= write_event_header_and_base64(ce, result_file, + print_event_info)) != + OK_CONTINUE) + goto end; } else ce->print(result_file, print_event_info, TRUE); @@ -604,17 +768,29 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, // If this binlog is not 3.23 ; why this test?? if (glob_description_event->binlog_version >= 3) { - if (load_processor.process(ce)) - break; // Error - ev= 0; + /* + transfer the responsibility for destroying the event to + load_processor + */ + ev= NULL; + if ((retval= load_processor.process(ce)) != OK_CONTINUE) + goto end; } break; } + case APPEND_BLOCK_EVENT: + /* + Append_block_log_events can safely print themselves even if + the subsequent call load_processor.process fails, because the + output of Append_block_log_event::print is only a comment. + */ ev->print(result_file, print_event_info); - if (load_processor.process((Append_block_log_event*) ev)) - break; // Error + if ((retval= load_processor.process((Append_block_log_event*) ev)) != + OK_CONTINUE) + goto end; break; + case EXEC_LOAD_EVENT: { ev->print(result_file, print_event_info); @@ -627,13 +803,18 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, */ if (ce) { + /* + We must not convert earlier, since the file is used by + my_open() in Load_log_processor::append(). + */ + convert_path_to_forward_slashes((char*) ce->fname); ce->print(result_file, print_event_info, TRUE); my_free((char*)ce->fname,MYF(MY_WME)); delete ce; } else - fprintf(stderr,"Warning: ignoring Exec_load as there is no \ -Create_file event for file_id: %u\n",exv->file_id); + warning("Ignoring Execute_load_log_event as there is no " + "Create_file event for file_id: %u", exv->file_id); break; } case FORMAT_DESCRIPTION_EVENT: @@ -653,41 +834,37 @@ Create_file event for file_id: %u\n",exv->file_id); if (!force_if_open_opt && (glob_description_event->flags & LOG_EVENT_BINLOG_IN_USE_F)) { - file_not_closed_error= 1; - DBUG_RETURN(1); + error("Attempting to dump binlog '%s', which was not closed properly. " + "Most probably, mysqld is still writing it, or it crashed. " + "Rerun with --force-if-open to ignore this problem.", logname); + DBUG_RETURN(ERROR_STOP); } break; case BEGIN_LOAD_QUERY_EVENT: ev->print(result_file, print_event_info); - load_processor.process((Begin_load_query_log_event*) ev); + if ((retval= load_processor.process((Begin_load_query_log_event*) ev)) != + OK_CONTINUE) + goto end; break; case EXECUTE_LOAD_QUERY_EVENT: { Execute_load_query_log_event *exlq= (Execute_load_query_log_event*)ev; char *fname= load_processor.grab_fname(exlq->file_id); - if (check_database(exlq->db)) + if (!shall_skip_database(exlq->db)) { if (fname) - my_free(fname, MYF(MY_WME)); - goto end; + { + convert_path_to_forward_slashes(fname); + exlq->print(result_file, print_event_info, fname); + } + else + warning("Ignoring Execute_load_query since there is no " + "Begin_load_query event for file_id: %u", exlq->file_id); } if (fname) - { - /* - Fix the path so it can be consumed by mysql client (requires Unix path). - */ - int stop= strlen(fname); - for (int i= 0; i < stop; i++) - if (fname[i] == '\\') - fname[i]= '/'; - exlq->print(result_file, print_event_info, fname); my_free(fname, MYF(MY_WME)); - } - else - fprintf(stderr,"Warning: ignoring Execute_load_query as there is no \ -Begin_load_query event for file_id: %u\n", exlq->file_id); break; } case TABLE_MAP_EVENT: @@ -706,20 +883,18 @@ Begin_load_query event for file_id: %u\n", exlq->file_id); */ if (!print_event_info->printed_fd_event && !short_form) { - /* - todo: a lot to clean up here - */ const char* type_str= ev->get_type_str(); - delete ev; if (opt_base64_output_mode == BASE64_OUTPUT_NEVER) - die("--base64-output=never specified, but binlog contains a " - "%s event which must be printed in base64.", - type_str); + error("--base64-output=never specified, but binlog contains a " + "%s event which must be printed in base64.", + type_str); else - die("malformed binlog: it does not contain any " - "Format_description_log_event. I now found a %s event, which is " - "not safe to process without a Format_description_log_event.", - type_str); + error("malformed binlog: it does not contain any " + "Format_description_log_event. I now found a %s event, which " + "is not safe to process without a " + "Format_description_log_event.", + type_str); + goto err; } /* FALL THROUGH */ default: @@ -727,6 +902,10 @@ Begin_load_query event for file_id: %u\n", exlq->file_id); } } + goto end; + +err: + retval= ERROR_STOP; end: rec_count++; /* @@ -739,7 +918,7 @@ end: ev->temp_buf= 0; delete ev; } - DBUG_RETURN(0); + DBUG_RETURN(retval); } @@ -894,16 +1073,71 @@ that may lead to an endless loop.", }; -void sql_print_error(const char *format,...) +/** + Auxiliary function used by error() and warning(). + + Prints the given text (normally "WARNING: " or "ERROR: "), followed + by the given vprintf-style string, followed by a newline. + + @param format Printf-style format string. + @param args List of arguments for the format string. + @param msg Text to print before the string. +*/ +static void error_or_warning(const char *format, va_list args, const char *msg) +{ + fprintf(stderr, "%s: ", msg); + vfprintf(stderr, format, args); + fprintf(stderr, "\n"); +} + +/** + Prints a message to stderr, prefixed with the text "ERROR: " and + suffixed with a newline. + + @param format Printf-style format string, followed by printf + varargs. +*/ +static void error(const char *format,...) { va_list args; va_start(args, format); - fprintf(stderr, "ERROR: "); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); + error_or_warning(format, args, "ERROR"); va_end(args); } + +/** + This function is used in log_event.cc to report errors. + + @param format Printf-style format string, followed by printf + varargs. +*/ +static void sql_print_error(const char *format,...) +{ + va_list args; + va_start(args, format); + error_or_warning(format, args, "ERROR"); + va_end(args); +} + +/** + Prints a message to stderr, prefixed with the text "WARNING: " and + suffixed with a newline. + + @param format Printf-style format string, followed by printf + varargs. +*/ +static void warning(const char *format,...) +{ + va_list args; + va_start(args, format); + error_or_warning(format, args, "WARNING"); + va_end(args); +} + +/** + Frees memory for global variables in this file. +*/ static void cleanup() { my_free(pass,MYF(MY_ALLOW_ZERO_PTR)); @@ -911,20 +1145,10 @@ static void cleanup() my_free((char*) host, MYF(MY_ALLOW_ZERO_PTR)); my_free((char*) user, MYF(MY_ALLOW_ZERO_PTR)); my_free((char*) dirname_for_local_load, MYF(MY_ALLOW_ZERO_PTR)); -} -static void die(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - fprintf(stderr, "ERROR: "); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); - va_end(args); - cleanup(); - /* We cannot free DBUG, it is used in global destructors after exit(). */ - my_end(my_end_arg | MY_DONT_FREE_DBUG); - exit(1); + delete glob_description_event; + if (mysql) + mysql_close(mysql); } #include @@ -962,7 +1186,7 @@ static my_time_t convert_str_to_timestamp(const char* str) if (str_to_datetime(str, strlen(str), &l_time, 0, &was_cut) != MYSQL_TIMESTAMP_DATETIME || was_cut) { - fprintf(stderr, "Incorrect date and time argument: %s\n", str); + error("Incorrect date and time argument: %s", str); exit(1); } /* @@ -1063,34 +1287,56 @@ static int parse_args(int *argc, char*** argv) return 0; } -static MYSQL* safe_connect() -{ - MYSQL *local_mysql= mysql_init(NULL); - if (!local_mysql) - die("Failed on mysql_init"); +/** + Create and initialize the global mysql object, and connect to the + server. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. +*/ +static Exit_status safe_connect() +{ + mysql= mysql_init(NULL); + + if (!mysql) + { + error("Failed on mysql_init."); + return ERROR_STOP; + } if (opt_protocol) - mysql_options(local_mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol); - if (!mysql_real_connect(local_mysql, host, user, pass, 0, port, sock, 0)) + mysql_options(mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol); + if (!mysql_real_connect(mysql, host, user, pass, 0, port, sock, 0)) { - char errmsg[256]; - strmake(errmsg, mysql_error(local_mysql), sizeof(errmsg)-1); - mysql_close(local_mysql); - die("failed on connect: %s", errmsg); + error("Failed on connect: %s", mysql_error(mysql)); + return ERROR_STOP; } - local_mysql->reconnect= 1; - return local_mysql; + mysql->reconnect= 1; + return OK_CONTINUE; } -static int dump_log_entries(const char* logname) +/** + High-level function for dumping a named binlog. + + This function calls dump_remote_log_entries() or + dump_local_log_entries() to do the job. + + @param[in] logname Name of input binlog. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. + @retval OK_STOP No error, but the end of the specified range of + events to process has been reached and the program should terminate. +*/ +static Exit_status dump_log_entries(const char* logname) { - int rc; + Exit_status rc; PRINT_EVENT_INFO print_event_info; if (!print_event_info.init_ok()) - return 1; + return ERROR_STOP; /* Set safe delimiter, to dump things like CREATE PROCEDURE safely @@ -1108,51 +1354,50 @@ static int dump_log_entries(const char* logname) } -/* - This is not as smart as check_header() (used for local log); it will not work - for a binlog which mixes format. TODO: fix this. +/** + When reading a remote binlog, this function is used to grab the + Format_description_log_event in the beginning of the stream. + + This is not as smart as check_header() (used for local log); it will + not work for a binlog which mixes format. TODO: fix this. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. */ -static int check_master_version(MYSQL *mysql_arg, - Format_description_log_event - **description_event) +static Exit_status check_master_version() { MYSQL_RES* res = 0; MYSQL_ROW row; const char* version; - if (mysql_query(mysql_arg, "SELECT VERSION()") || - !(res = mysql_store_result(mysql_arg))) + if (mysql_query(mysql, "SELECT VERSION()") || + !(res = mysql_store_result(mysql))) { - /* purecov: begin inspected */ - char errmsg[256]; - strmake(errmsg, mysql_error(mysql_arg), sizeof(errmsg)-1); - mysql_close(mysql_arg); - die("Error checking master version: %s", errmsg); - /* purecov: end */ + error("Could not find server version: " + "Query failed when checking master version: %s", mysql_error(mysql)); + return ERROR_STOP; } if (!(row = mysql_fetch_row(res))) { - /* purecov: begin inspected */ - mysql_free_result(res); - mysql_close(mysql); - die("Master returned no rows for SELECT VERSION()"); - /* purecov: end */ - } - if (!(version = row[0])) - { - /* purecov: begin inspected */ - mysql_free_result(res); - mysql_close(mysql_arg); - die("Master reported NULL for the version"); - /* purecov: end */ + error("Could not find server version: " + "Master returned no rows for SELECT VERSION()."); + goto err; } + if (!(version = row[0])) + { + error("Could not find server version: " + "Master reported NULL for the version."); + goto err; + } + + delete glob_description_event; switch (*version) { case '3': - *description_event= new Format_description_log_event(1); + glob_description_event= new Format_description_log_event(1); break; case '4': - *description_event= new Format_description_log_event(3); + glob_description_event= new Format_description_log_event(3); break; case '5': /* @@ -1161,31 +1406,53 @@ static int check_master_version(MYSQL *mysql_arg, So we first assume that this is 4.0 (which is enough to read the Format_desc event if one comes). */ - *description_event= new Format_description_log_event(3); + glob_description_event= new Format_description_log_event(3); break; default: - /* purecov: begin inspected */ - mysql_free_result(res); - mysql_close(mysql_arg); - die("Master reported unrecognized MySQL version '%s'", version); - /* purecov: end */ + glob_description_event= NULL; + error("Could not find server version: " + "Master reported unrecognized MySQL version '%s'.", version); + goto err; } + if (!glob_description_event || !glob_description_event->is_valid()) + { + error("Failed creating Format_description_log_event; out of memory?"); + goto err; + } + mysql_free_result(res); - return 0; + return OK_CONTINUE; + +err: + mysql_free_result(res); + return ERROR_STOP; } -static int dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, - const char* logname) +/** + Requests binlog dump from a remote server and prints the events it + receives. + + @param[in,out] print_event_info Parameters and context state + determining how to print. + @param[in] logname Name of input binlog. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. + @retval OK_STOP No error, but the end of the specified range of + events to process has been reached and the program should terminate. +*/ +static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, + const char* logname) { uchar buf[128]; ulong len; uint logname_len; NET* net; - int error= 0; my_off_t old_off= start_position_mot; char fname[FN_REFLEN+1]; + Exit_status retval= OK_CONTINUE; DBUG_ENTER("dump_remote_log_entries"); /* @@ -1193,20 +1460,12 @@ static int dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, we cannot re-use the same connection as before, because it is now dead (COM_BINLOG_DUMP kills the thread when it finishes). */ - mysql= safe_connect(); + if ((retval= safe_connect()) != OK_CONTINUE) + DBUG_RETURN(retval); net= &mysql->net; - if (check_master_version(mysql, &glob_description_event)) - { - fprintf(stderr, "Could not find server version"); - DBUG_RETURN(1); - } - if (!glob_description_event || !glob_description_event->is_valid()) - { - fprintf(stderr, "Invalid Format_description log event; \ -could be out of memory"); - DBUG_RETURN(1); - } + if ((retval= check_master_version()) != OK_CONTINUE) + DBUG_RETURN(retval); /* COM_BINLOG_DUMP accepts only 4 bytes for the position, so we are forced to @@ -1218,18 +1477,16 @@ could be out of memory"); size_t tlen = strlen(logname); if (tlen > UINT_MAX) { - fprintf(stderr,"Log name too long\n"); - error= 1; - goto err; + error("Log name too long."); + DBUG_RETURN(ERROR_STOP); } logname_len = (uint) tlen; int4store(buf + 6, 0); memcpy(buf + 10, logname, logname_len); if (simple_command(mysql, COM_BINLOG_DUMP, buf, logname_len + 10, 1)) { - fprintf(stderr,"Got fatal error sending the log dump command\n"); - error= 1; - goto err; + error("Got fatal error sending the log dump command."); + DBUG_RETURN(ERROR_STOP); } for (;;) @@ -1240,10 +1497,8 @@ could be out of memory"); len= cli_safe_read(mysql); if (len == packet_error) { - fprintf(stderr, "Got error reading packet from server: %s\n", - mysql_error(mysql)); - error= 1; - goto err; + error("Got error reading packet from server: %s", mysql_error(mysql)); + DBUG_RETURN(ERROR_STOP); } if (len < 8 && net->read_pos[0] == 254) break; // end of data @@ -1253,9 +1508,8 @@ could be out of memory"); len - 1, &error_msg, glob_description_event))) { - fprintf(stderr, "Could not construct log event object\n"); - error= 1; - goto err; + error("Could not construct log event object: %s", error_msg); + DBUG_RETURN(ERROR_STOP); } /* If reading from a remote host, ensure the temp_buf for the @@ -1294,8 +1548,7 @@ could be out of memory"); if ((rev->ident_len != logname_len) || memcmp(rev->new_log_ident, logname, logname_len)) { - error= 0; - goto err; + DBUG_RETURN(OK_CONTINUE); } /* Otherwise, this is a fake Rotate for our log, at the very @@ -1320,11 +1573,9 @@ could be out of memory"); if (old_off != BIN_LOG_HEADER_SIZE) len= 1; // fake event, don't increment old_off } - if ((error= process_event(print_event_info, ev, old_off))) - { - error= ((error < 0) ? 0 : 1); - goto err; - } + Exit_status retval= process_event(print_event_info, ev, old_off, logname); + if (retval != OK_CONTINUE) + DBUG_RETURN(retval); } else { @@ -1332,26 +1583,21 @@ could be out of memory"); const char *old_fname= le->fname; uint old_len= le->fname_len; File file; + Exit_status retval; if ((file= load_processor.prepare_new_file_for_old_format(le,fname)) < 0) - { - error= 1; - goto err; - } + DBUG_RETURN(ERROR_STOP); - if ((error= process_event(print_event_info, ev, old_off))) + retval= process_event(print_event_info, ev, old_off, logname); + if (retval != OK_CONTINUE) { my_close(file,MYF(MY_WME)); - error= ((error < 0) ? 0 : 1); - goto err; + DBUG_RETURN(retval); } - error= load_processor.load_old_format_file(net,old_fname,old_len,file); + retval= load_processor.load_old_format_file(net,old_fname,old_len,file); my_close(file,MYF(MY_WME)); - if (error) - { - error= 1; - goto err; - } + if (retval != OK_CONTINUE) + DBUG_RETURN(retval); } /* Let's adjust offset for remote log as for local log to produce @@ -1360,15 +1606,13 @@ could be out of memory"); old_off+= len-1; } -err: - mysql_close(mysql); - DBUG_RETURN(error); + DBUG_RETURN(OK_CONTINUE); } /** - Reads the @c Format_description_log_event from the beginning of the - input file. + Reads the @c Format_description_log_event from the beginning of a + local input file. The @c Format_description_log_event is only read if it is outside the range specified with @c --start-position; otherwise, it will be @@ -1382,32 +1626,42 @@ err: @param file The file to which a @c Format_description_log_event will be printed. - @param description_event Pointer to the global @c - Format_description_log_event pointer. This will be updated if a new - Format_description_log_event is found. + @param[in,out] print_event_info Parameters and context state + determining how to print. - @param print_event_info Context state needed to print events. + @param[in] logname Name of input binlog. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. + @retval OK_STOP No error, but the end of the specified range of + events to process has been reached and the program should terminate. */ -static void check_header(IO_CACHE* file, - Format_description_log_event **description_event, - PRINT_EVENT_INFO *print_event_info) +static Exit_status check_header(IO_CACHE* file, + PRINT_EVENT_INFO *print_event_info, + const char* logname) { uchar header[BIN_LOG_HEADER_SIZE]; uchar buf[PROBE_HEADER_LEN]; my_off_t tmp_pos, pos; - *description_event= new Format_description_log_event(3); + delete glob_description_event; + if (!(glob_description_event= new Format_description_log_event(3))) + { + error("Failed creating Format_description_log_event; out of memory?"); + return ERROR_STOP; + } + pos= my_b_tell(file); my_b_seek(file, (my_off_t)0); if (my_b_read(file, header, sizeof(header))) { - delete *description_event; - die("Failed reading header; Probably an empty file"); + error("Failed reading header; probably an empty file."); + return ERROR_STOP; } if (memcmp(header, BINLOG_MAGIC, sizeof(header))) { - delete *description_event; - die("File is not a binary log file"); + error("File is not a binary log file."); + return ERROR_STOP; } /* @@ -1430,10 +1684,9 @@ static void check_header(IO_CACHE* file, { if (file->error) { - delete *description_event; - die("\ -Could not read entry at offset %lu : Error in log format or read error", - tmp_pos); + error("Could not read entry at offset %llu: " + "Error in log format or read error.", (ulonglong)tmp_pos); + return ERROR_STOP; } /* Otherwise this is just EOF : this log currently contains 0-2 @@ -1463,8 +1716,13 @@ Could not read entry at offset %lu : Error in log format or read error", (LOG_EVENT_MINIMAL_HEADER_LEN + START_V3_HEADER_LEN)) { /* This is 3.23 (format 1) */ - delete *description_event; - *description_event= new Format_description_log_event(1); + delete glob_description_event; + if (!(glob_description_event= new Format_description_log_event(1))) + { + error("Failed creating Format_description_log_event; " + "out of memory?"); + return ERROR_STOP; + } } break; } @@ -1476,26 +1734,32 @@ Could not read entry at offset %lu : Error in log format or read error", Format_description_log_event *new_description_event; my_b_seek(file, tmp_pos); /* seek back to event's start */ if (!(new_description_event= (Format_description_log_event*) - Log_event::read_log_event(file, *description_event))) + Log_event::read_log_event(file, glob_description_event))) /* EOF can't be hit here normally, so it's a real error */ { - delete *description_event; - die("Could not read a Format_description_log_event event \ -at offset %lu ; this could be a log format error or read error", - tmp_pos); + error("Could not read a Format_description_log_event event at " + "offset %llu; this could be a log format error or read error.", + (ulonglong)tmp_pos); + return ERROR_STOP; } if (opt_base64_output_mode == BASE64_OUTPUT_AUTO || opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) + { /* process_event will delete *description_event and set it to the new one, so we should not do it ourselves in this case. */ - process_event(print_event_info, new_description_event, tmp_pos); + Exit_status retval= process_event(print_event_info, + new_description_event, tmp_pos, + logname); + if (retval != OK_CONTINUE) + return retval; + } else { - delete *description_event; - *description_event= new_description_event; + delete glob_description_event; + glob_description_event= new_description_event; } DBUG_PRINT("info",("Setting description_event")); } @@ -1503,12 +1767,13 @@ at offset %lu ; this could be a log format error or read error", { Log_event *ev; my_b_seek(file, tmp_pos); /* seek back to event's start */ - if (!(ev= Log_event::read_log_event(file, *description_event))) - /* EOF can't be hit here normally, so it's a real error */ + if (!(ev= Log_event::read_log_event(file, glob_description_event))) { - delete *description_event; - die("Could not read a Rotate_log_event event at offset %lu ;" - " this could be a log format error or read error", tmp_pos); + /* EOF can't be hit here normally, so it's a real error */ + error("Could not read a Rotate_log_event event at offset %llu;" + " this could be a log format error or read error.", + (ulonglong)tmp_pos); + return ERROR_STOP; } delete ev; } @@ -1517,31 +1782,48 @@ at offset %lu ; this could be a log format error or read error", } } my_b_seek(file, pos); + return OK_CONTINUE; } -static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, - const char* logname) +/** + Reads a local binlog and prints the events it sees. + + @param[in] logname Name of input binlog. + + @param[in,out] print_event_info Parameters and context state + determining how to print. + + @retval ERROR_STOP An error occurred - the program should terminate. + @retval OK_CONTINUE No error, the program should continue. + @retval OK_STOP No error, but the end of the specified range of + events to process has been reached and the program should terminate. +*/ +static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, + const char* logname) { File fd = -1; IO_CACHE cache,*file= &cache; uchar tmp_buff[BIN_LOG_HEADER_SIZE]; - int error= 0; + Exit_status retval= OK_CONTINUE; if (logname && strcmp(logname, "-") != 0) { + /* read from normal file */ if ((fd = my_open(logname, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0) - return 1; + return ERROR_STOP; if (init_io_cache(file, fd, 0, READ_CACHE, start_position_mot, 0, MYF(MY_WME | MY_NABP))) { my_close(fd, MYF(MY_WME)); - return 1; + return ERROR_STOP; } - check_header(file, &glob_description_event, print_event_info); + if ((retval= check_header(file, print_event_info, logname)) != OK_CONTINUE) + goto end; } - else // reading from stdin; + else { + /* read from stdin */ /* Windows opens stdin in text mode by default. Certain characters such as CTRL-Z are interpeted as events and the read() method @@ -1553,14 +1835,18 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, #if defined (__WIN__) || (_WIN64) if (_setmode(fileno(stdin), O_BINARY) == -1) { - fprintf(stderr, "Could not set binary mode on stdin.\n"); - return 1; + error("Could not set binary mode on stdin."); + return ERROR_STOP; } #endif if (init_io_cache(file, fileno(stdin), 0, READ_CACHE, (my_off_t) 0, 0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE))) - return 1; - check_header(file, &glob_description_event, print_event_info); + { + error("Failed to init IO cache."); + return ERROR_STOP; + } + if ((retval= check_header(file, print_event_info, logname)) != OK_CONTINUE) + goto end; if (start_position) { /* skip 'start_position' characters from stdin */ @@ -1571,8 +1857,8 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, tmp=min(length,sizeof(buff)); if (my_b_read(file, buff, (uint) tmp)) { - error= 1; - goto end; + error("Failed reading from file."); + goto err; } } } @@ -1580,14 +1866,14 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, if (!glob_description_event || !glob_description_event->is_valid()) { - delete glob_description_event; - die("Invalid Format_description log event; could be out of memory"); + error("Invalid Format_description log event; could be out of memory."); + goto err; } if (!start_position && my_b_read(file, tmp_buff, BIN_LOG_HEADER_SIZE)) { - error= 1; - goto end; + error("Failed reading from file."); + goto err; } for (;;) { @@ -1605,36 +1891,36 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, file->error= 0; else if (file->error) { - fprintf(stderr, - "Could not read entry at offset %s:" - "Error in log format or read error\n", - llstr(old_off,llbuff)); - error= 1; + error("Could not read entry at offset %s: " + "Error in log format or read error.", + llstr(old_off,llbuff)); + goto err; } // file->error == 0 means EOF, that's OK, we break in this case - break; - } - if ((error= process_event(print_event_info, ev, old_off))) - { - if (error < 0) - error= 0; - break; + goto end; } + if ((retval= process_event(print_event_info, ev, old_off, logname)) != + OK_CONTINUE) + goto end; } + /* NOTREACHED */ + +err: + retval= ERROR_STOP; + end: if (fd >= 0) my_close(fd, MYF(MY_WME)); end_io_cache(file); - delete glob_description_event; - return error; + return retval; } int main(int argc, char** argv) { char **defaults_argv; - int exit_value= 0; + Exit_status retval= OK_CONTINUE; ulonglong save_stop_position; MY_INIT(argv[0]); DBUG_ENTER("main"); @@ -1696,15 +1982,13 @@ int main(int argc, char** argv) "\n/*!40101 SET NAMES %s */;\n", charset); for (save_stop_position= stop_position, stop_position= ~(my_off_t)0 ; - (--argc >= 0) && !stop_passed ; ) + (--argc >= 0) ; ) { if (argc == 0) // last log, --stop-position applies stop_position= save_stop_position; - if (dump_log_entries(*(argv++))) - { - exit_value=1; + if ((retval= dump_log_entries(*argv++)) != OK_CONTINUE) break; - } + // For next log, --start-position does not apply start_position= BIN_LOG_HEADER_SIZE; } @@ -1736,17 +2020,9 @@ int main(int argc, char** argv) /* We cannot free DBUG, it is used in global destructors after exit(). */ my_end(my_end_arg | MY_DONT_FREE_DBUG); - if (file_not_closed_error) - { - fprintf(stderr, -"\nError: attempting to dump binlog '%s' which was not closed properly.\n" -"Most probably mysqld is still writting it, or crashed.\n" -"Your current options specify --disable-force-if-open\n" -"which means to abort on this problem.\n" -"You can rerun using --force-if-open to ignore this problem.\n\n", argv[-1]); - } - exit(exit_value); - DBUG_RETURN(exit_value); // Keep compilers happy + exit(retval == ERROR_STOP ? 1 : 0); + /* Keep compilers happy. */ + DBUG_RETURN(retval == ERROR_STOP ? 1 : 0); } /* diff --git a/client/mysqltest.c b/client/mysqltest.c index 31e419244e6..fdbd31fab36 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -45,6 +45,10 @@ #ifdef HAVE_SYS_WAIT_H #include #endif +#ifdef __WIN__ +#include +#endif + /* Use cygwin for --exec and --system before 5.0 */ #if MYSQL_VERSION_ID < 50000 @@ -263,7 +267,7 @@ enum enum_commands { Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST, Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP, Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES, - Q_SEND_QUIT, Q_CHANGE_USER, + Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ @@ -353,6 +357,9 @@ const char *command_names[]= "diff_files", "send_quit", "change_user", + "mkdir", + "rmdir", + 0 }; @@ -2736,6 +2743,67 @@ void do_file_exist(struct st_command *command) } +/* + SYNOPSIS + do_mkdir + command called command + + DESCRIPTION + mkdir + Create the directory +*/ + +void do_mkdir(struct st_command *command) +{ + int error; + static DYNAMIC_STRING ds_dirname; + const struct command_arg mkdir_args[] = { + "dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to create" + }; + DBUG_ENTER("do_mkdir"); + + check_command_args(command, command->first_argument, + mkdir_args, sizeof(mkdir_args)/sizeof(struct command_arg), + ' '); + + DBUG_PRINT("info", ("creating directory: %s", ds_dirname.str)); + error= my_mkdir(ds_dirname.str, 0777, MYF(0)) != 0; + handle_command_error(command, error); + dynstr_free(&ds_dirname); + DBUG_VOID_RETURN; +} + +/* + SYNOPSIS + do_rmdir + command called command + + DESCRIPTION + rmdir + Remove the empty directory +*/ + +void do_rmdir(struct st_command *command) +{ + int error; + static DYNAMIC_STRING ds_dirname; + const struct command_arg rmdir_args[] = { + "dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to remove" + }; + DBUG_ENTER("do_rmdir"); + + check_command_args(command, command->first_argument, + rmdir_args, sizeof(rmdir_args)/sizeof(struct command_arg), + ' '); + + DBUG_PRINT("info", ("removing directory: %s", ds_dirname.str)); + error= rmdir(ds_dirname.str) != 0; + handle_command_error(command, error); + dynstr_free(&ds_dirname); + DBUG_VOID_RETURN; +} + + /* Read characters from line buffer or file. This is needed to allow my_ungetc() to buffer MAX_DELIMITER_LENGTH characters for a file @@ -6913,6 +6981,8 @@ 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_MKDIR: do_mkdir(command); break; + case Q_RMDIR: do_rmdir(command); break; case Q_FILE_EXIST: do_file_exist(command); break; case Q_WRITE_FILE: do_write_file(command); break; case Q_APPEND_FILE: do_append_file(command); break; diff --git a/configure.in b/configure.in index 1346a87c35a..2e623aacaf7 100644 --- a/configure.in +++ b/configure.in @@ -813,8 +813,8 @@ AC_CHECK_HEADERS(fcntl.h float.h floatingpoint.h ieeefp.h limits.h \ sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \ unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \ sys/ioctl.h malloc.h sys/malloc.h sys/ipc.h sys/shm.h linux/config.h \ - sys/prctl.h \ - sys/resource.h sys/param.h port.h ieeefp.h) + sys/prctl.h sys/resource.h sys/param.h port.h ieeefp.h \ + execinfo.h) AC_CHECK_HEADERS([xfs/xfs.h]) @@ -2041,7 +2041,7 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bsearch bzero \ sighold sigset sigthreadmask port_create sleep \ snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \ strtol strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr \ - posix_fallocate) + posix_fallocate backtrace backtrace_symbols backtrace_symbols_fd) # # @@ -2331,6 +2331,21 @@ then fi AC_MSG_RESULT("$netinet_inc") +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +AC_CHECK_HEADERS(cxxabi.h) +AC_CACHE_CHECK([checking for abi::__cxa_demangle], mysql_cv_cxa_demangle, +[AC_TRY_LINK([#include ], [ + char *foo= 0; int bar= 0; + foo= abi::__cxa_demangle(foo, foo, 0, &bar); +], [mysql_cv_cxa_demangle=yes], [mysql_cv_cxa_demangle=no])]) +AC_LANG_RESTORE + +if test "x$mysql_cv_cxa_demangle" = xyes; then + AC_DEFINE(HAVE_ABI_CXA_DEMANGLE, 1, + [Define to 1 if you have the `abi::__cxa_demangle' function.]) +fi + #-------------------------------------------------------------------- # Check for requested features #-------------------------------------------------------------------- diff --git a/include/my_base.h b/include/my_base.h index 947f7695215..4f552fa5fe0 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -419,7 +419,9 @@ enum ha_base_keytype { statement */ #define HA_ERR_CORRUPT_EVENT 171 /* The event was corrupt, leading to illegal data being read */ -#define HA_ERR_LAST 171 /*Copy last error nr.*/ +#define HA_ERR_ROWS_EVENT_APPLY 172 /* The event could not be processed + no other hanlder error happened */ +#define HA_ERR_LAST 172 /*Copy last error nr.*/ /* Add error numbers before HA_ERR_LAST and change it accordingly. */ #define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1) diff --git a/mysql-test/extra/binlog_tests/binlog.test b/mysql-test/extra/binlog_tests/binlog.test index 0d2ed7ad509..48fc5a81c7b 100644 --- a/mysql-test/extra/binlog_tests/binlog.test +++ b/mysql-test/extra/binlog_tests/binlog.test @@ -108,6 +108,23 @@ drop table t1; set global binlog_cache_size=@bcs; set session autocommit = @ac; +# +# Bug#33798: prepared statements improperly handle large unsigned ints +# +--disable_warnings +drop table if exists t1; +--enable_warnings +reset master; +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +execute stmt using @a, @b; +deallocate prepare stmt; +drop table t1; +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/ +show binlog events from 0; + --echo End of 5.0 tests # Test of a too big SET INSERT_ID: see if the truncated value goes diff --git a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test index b5795cf525d..0e391cb0f37 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test +++ b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test @@ -46,7 +46,7 @@ ALTER TABLE t1_bit ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; # ... and add one non-nullable INT column last in table 't1_text' # with no default, -ALTER TABLE t1_nodef ADD x INT NOT NULL; +ALTER TABLE t1_nodef ADD x INT NOT NULL, ADD y INT NOT NULL, ADD z INT NOT NULL; # ... and remove the last column in t2 ALTER TABLE t2 DROP b; # ... change the type of the single column in table 't4' @@ -222,8 +222,8 @@ sync_slave_with_master; --echo **** On Slave **** connection slave; -INSERT INTO t1_nodef VALUES (1,2,3); -INSERT INTO t1_nodef VALUES (2,4,6); +INSERT INTO t1_nodef VALUES (1,2,3,4,5); +INSERT INTO t1_nodef VALUES (2,4,6,8,10); --echo **** On Master **** connection master; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index e405e01ea8f..7f4312130c2 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3877,14 +3877,6 @@ sub mysqld_arguments ($$$$) { mtr_add_arg($args, "%s--user=root"); } - # When mysqld is run by a root user(euid is 0), it will fail - # to start unless we specify what user to run as, see BUG#30630 - my $euid= $>; - if (!$glob_win32 and $euid == 0 and - (grep(/^--user/, @$extra_opt, @opt_extra_mysqld_opt)) == 0) { - mtr_add_arg($args, "%s--user=root", $prefix); - } - if ( $opt_valgrind_mysqld ) { mtr_add_arg($args, "%s--skip-safemalloc", $prefix); diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 0613c9ba488..4bdcca81b74 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1743,4 +1743,50 @@ t1 CREATE TABLE `t1` ( `MAXLEN` bigint(3) NOT NULL DEFAULT '0' ) ENGINE=MEMORY DEFAULT CHARSET=utf8 drop table t1; + +# -- +# -- Bug#21380: DEFAULT definition not always transfered by CREATE +# -- TABLE/SELECT to the new table. +# -- + +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; + +CREATE TABLE t1( +c1 INT DEFAULT 12 COMMENT 'column1', +c2 INT NULL COMMENT 'column2', +c3 INT NOT NULL COMMENT 'column3', +c4 VARCHAR(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a', +c5 VARCHAR(255) COLLATE utf8_unicode_ci NULL DEFAULT 'b', +c6 VARCHAR(255)) +COLLATE latin1_bin; + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) DEFAULT '12' COMMENT 'column1', + `c2` int(11) DEFAULT NULL COMMENT 'column2', + `c3` int(11) NOT NULL COMMENT 'column3', + `c4` varchar(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a', + `c5` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT 'b', + `c6` varchar(255) COLLATE latin1_bin DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_bin + +CREATE TABLE t2 AS SELECT * FROM t1; + +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `c1` int(11) DEFAULT '12' COMMENT 'column1', + `c2` int(11) DEFAULT NULL COMMENT 'column2', + `c3` int(11) NOT NULL COMMENT 'column3', + `c4` varchar(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a', + `c5` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT 'b', + `c6` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +DROP TABLE t2; + +# -- End of test case for Bug#21380. + End of 5.1 tests diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index b91e7e88d64..814cf42d16c 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -722,4 +722,17 @@ DROP USER mysqltest_u1@localhost; # ##################################################################### +drop procedure if exists p; +set @old_mode= @@sql_mode; +set @@sql_mode= pow(2,32)-1; +create event e1 on schedule every 1 day do select 1; +select @@sql_mode; +@@sql_mode +REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,?,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH +set @@sql_mode= @old_mode; +select replace(@full_mode, '?', 'NOT_USED') into @full_mode; +select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode; +select name from mysql.event where name = 'p' and sql_mode = @full_mode; +name +drop event e1; DROP DATABASE events_test; diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 0df3ac6de8a..c157e1d4706 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1218,6 +1218,28 @@ DROP USER mysqltest_1@localhost; DROP DATABASE db27878; use test; DROP TABLE t1; +drop table if exists test; +Warnings: +Note 1051 Unknown table 'test' +drop function if exists test_function; +Warnings: +Note 1305 FUNCTION test_function does not exist +drop view if exists v1; +Warnings: +Note 1051 Unknown table 'test.v1' +create table test (col1 varchar(30)); +create function test_function() returns varchar(30) +begin +declare tmp varchar(30); +select col1 from test limit 1 into tmp; +return '1'; +end| +create view v1 as select test.* from test where test.col1=test_function(); +grant update (col1) on v1 to 'greg'@'localhost'; +drop user 'greg'@'localhost'; +drop view v1; +drop table test; +drop function test_function; End of 5.0 tests set names utf8; grant select on test.* to юзер_юзер@localhost; @@ -1282,5 +1304,6 @@ CALL mysqltest1.test(); 1 DROP DATABASE mysqltest1; RENAME TABLE mysql.procs_gone TO mysql.procs_priv; +DROP USER mysqltest_1@localhost; FLUSH PRIVILEGES; End of 5.1 tests diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index ddc0e189cd2..708d8ab027d 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -588,7 +588,7 @@ proc body longblob proc definer char(77) proc created timestamp proc modified timestamp -proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') +proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') proc comment char(64) proc character_set_client char(32) proc collation_connection char(32) @@ -1623,4 +1623,19 @@ Db Name Definer Time zone Type Execute at Interval value Interval field Starts E show events where Db= 'information_schema'; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation use test; +# +# Bug#34166: Server crash in SHOW OPEN TABLES and prelocking +# +drop table if exists t1; +drop function if exists f1; +create table t1 (a int); +create function f1() returns int +begin +insert into t1 (a) values (1); +return 0; +end| +show open tables where f1()=0; +show open tables where f1()=0; +drop table t1; +drop function f1; End of 5.1 tests. diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result index 9c4f1b17dcc..cd05fc1473f 100644 --- a/mysql-test/r/lock_multi.result +++ b/mysql-test/r/lock_multi.result @@ -143,4 +143,14 @@ connection: default flush tables; unlock tables; drop table t1; +drop table if exists t1,t2; +create table t1 (a int); +flush status; +lock tables t1 read; +insert into t1 values(1);; +unlock tables; +drop table t1; +select @tlwa < @tlwb; +@tlwa < @tlwb +1 End of 5.1 tests diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index a6b07bfc127..75d3f79f4b0 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1717,6 +1717,22 @@ t1 CREATE TABLE `t1` ( `?` decimal(2,1) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +drop table if exists t1; +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +insert into t1 values (@a, @b); +select * from t1 where a = @a and b = @b; +a b +9999999999999999 14632475938453979136 +execute stmt using @a, @b; +select * from t1 where a = @a and b = @b; +a b +9999999999999999 14632475938453979136 +9999999999999999 14632475938453979136 +deallocate prepare stmt; +drop table t1; End of 5.0 tests. create procedure proc_1() reset query cache; call proc_1(); diff --git a/mysql-test/r/ps_ddl.result b/mysql-test/r/ps_ddl.result index 0987e765265..531d29d219e 100644 --- a/mysql-test/r/ps_ddl.result +++ b/mysql-test/r/ps_ddl.result @@ -1,10 +1,11 @@ +SELECT VARIABLE_VALUE from +INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' +into @base_count ; +set @expected = 0; ===================================================================== Testing 1: NOTHING -> TABLE transitions ===================================================================== drop table if exists t1; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; prepare stmt from 'select * from t1'; ERROR 42S02: Table 'test.t1' doesn't exist ===================================================================== @@ -17,92 +18,144 @@ Testing 3: NOTHING -> VIEW transitions Testing 4: TABLE -> NOTHING transitions ===================================================================== drop table if exists t4; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t4(a int); prepare stmt from 'select * from t4'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t4; execute stmt; ERROR 42S02: Table 'test.t4' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; ERROR 42S02: Table 'test.t4' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 ===================================================================== Testing 5: TABLE -> TABLE (DDL) transitions ===================================================================== drop table if exists t5; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t5(a int); -prepare stmt from 'select * from t5'; +prepare stmt from 'select a from t5'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t5 add column (b int); +set @expected = @expected + 1; execute stmt; -a b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +a +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; -a b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +a +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t5; ===================================================================== Testing 6: TABLE -> TABLE (TRIGGER) transitions ===================================================================== drop table if exists t6; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t6(a int); prepare stmt from 'insert into t6(a) value (?)'; set @val=1; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 set @val=2; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 create trigger t6_bi before insert on t6 for each row begin set @message= "t6_bi"; @@ -110,20 +163,33 @@ end $$ set @message="none"; set @val=3; +set @expected = @expected + 1; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi set @val=4; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi @@ -131,20 +197,32 @@ prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=5; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi set @message="none"; set @val=6; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi @@ -155,21 +233,34 @@ end $$ set @message="none"; set @val=7; +set @expected = @expected + 1; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi set @message="none"; set @val=8; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi @@ -177,20 +268,32 @@ prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=9; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi set @message="none"; set @val=10; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi @@ -202,20 +305,33 @@ end $$ set @message="none"; set @val=11; +set @expected = @expected + 1; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi (2) set @val=12; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi (2) @@ -223,20 +339,32 @@ prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=13; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi (2) set @message="none"; set @val=14; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi (2) @@ -248,21 +376,34 @@ end $$ set @message="none"; set @val=15; +set @expected = @expected + 1; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi (2) set @message="none"; set @val=16; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi (2) @@ -270,40 +411,65 @@ prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=17; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi (2) set @message="none"; set @val=18; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message t6_bi (2) drop trigger t6_bi; set @message="none"; set @val=19; +set @expected = @expected + 1; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message none set @val=20; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message none @@ -311,38 +477,63 @@ prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=21; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message none set @val=22; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message none drop trigger t6_bd; set @val=23; +set @expected = @expected + 1; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message none set @val=24; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select @message; @message none @@ -386,9 +577,6 @@ drop table if exists t7_audit; drop procedure if exists audit_proc; drop function if exists audit_func; drop view if exists audit_view; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t7_proc(a int); create table t7_func(a int); create table t7_view(a int); @@ -414,155 +602,294 @@ for each row set NEW.reason="trigger v1"; prepare stmt_proc from 'insert into t7_proc(a) value (?)'; set @val=101; execute stmt_proc using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 set @val=102; execute stmt_proc using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop procedure audit_proc; create procedure audit_proc(a int) insert into t7_audit values (NULL, a, "proc v2"); set @val=103; +set @expected = @expected + 1; execute stmt_proc using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 set @val=104; execute stmt_proc using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 prepare stmt_func from 'insert into t7_func(a) value (?)'; set @val=201; execute stmt_func using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 set @val=202; execute stmt_func using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop function audit_func; create function audit_func() returns varchar(50) return "func v2"; set @val=203; +set @expected = @expected + 1; execute stmt_func using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 set @val=204; execute stmt_func using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 prepare stmt_view from 'insert into t7_view(a) value (?)'; set @val=301; execute stmt_view using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 set @val=302; execute stmt_view using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop view audit_view; create view audit_view as select "view v2" as reason from dual; set @val=303; +set @expected = @expected + 1; execute stmt_view using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 set @val=304; execute stmt_view using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 prepare stmt_table from 'insert into t7_table(a) value (?)'; set @val=401; execute stmt_table using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 set @val=402; execute stmt_table using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t7_dependent_table add column comments varchar(100) default NULL; set @val=403; +set @expected = @expected + 1; execute stmt_table using @val; ERROR 21S01: Column count doesn't match value count at row 1 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 set @val=404; +set @expected = @expected + 1; execute stmt_table using @val; ERROR 21S01: Column count doesn't match value count at row 1 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t7_dependent_table drop column comments; set @val=405; +set @expected = @expected + 1; execute stmt_table using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -3 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 set @val=406; execute stmt_table using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -3 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 prepare stmt_table_trigger from 'insert into t7_table(a) value (?)'; set @val=501; execute stmt_table_trigger using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -3 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 set @val=502; execute stmt_table_trigger using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -3 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop trigger t7_table_trigger_bi; create trigger t7_table_trigger_bi before insert on t7_dependent_table for each row set NEW.reason="trigger v2"; set @val=503; +set @expected = @expected + 1; execute stmt_table_trigger using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -4 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 set @val=504; execute stmt_table_trigger using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -4 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select * from t7_audit order by new_a; old_a new_a reason NULL 101 proc v1 @@ -601,150 +928,237 @@ drop view audit_view; Testing 8: TABLE -> TEMPORARY TABLE transitions ===================================================================== drop table if exists t8; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t8(a int); prepare stmt from 'select * from t8'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t8; create temporary table t8(a int); +set @expected = @expected + 1; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t8; ===================================================================== Testing 9: TABLE -> VIEW transitions ===================================================================== drop table if exists t9; drop table if exists t9_b; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t9(a int); create table t9_b(a int); prepare stmt from 'select * from t9'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t9; create view t9 as select * from t9_b; +set @expected = @expected + 1; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop view t9; drop table t9_b; ===================================================================== Testing 10: TEMPORARY TABLE -> NOTHING transitions ===================================================================== drop temporary table if exists t10; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create temporary table t10(a int); prepare stmt from 'select * from t10'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop temporary table t10; execute stmt; ERROR 42S02: Table 'test.t10' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; ERROR 42S02: Table 'test.t10' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 ===================================================================== Testing 11: TEMPORARY TABLE -> TABLE transitions ===================================================================== drop table if exists t11; drop temporary table if exists t11; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t11(a int); insert into t11(a) value (1); create temporary table t11(a int); prepare stmt from 'select * from t11'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop temporary table t11; +set @expected = @expected + 1; execute stmt; a 1 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a 1 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select * from t11; a 1 @@ -753,37 +1167,59 @@ drop table t11; Testing 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL) transitions ===================================================================== drop temporary table if exists t12; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create temporary table t12(a int); -prepare stmt from 'select * from t12'; +prepare stmt from 'select a from t12'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop temporary table t12; create temporary table t12(a int, b int); +set @expected = @expected + 1; execute stmt; -a b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +a +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; -a b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +a +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select * from t12; a b drop table t12; @@ -792,38 +1228,60 @@ Testing 13: TEMPORARY TABLE -> VIEW transitions ===================================================================== drop temporary table if exists t13; drop table if exists t13_b; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create temporary table t13(a int); create table t13_b(a int); prepare stmt from 'select * from t13'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop temporary table t13; create view t13 as select * from t13_b; +set @expected = @expected + 1; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop view t13; drop table t13_b; ===================================================================== @@ -831,75 +1289,120 @@ Testing 14: VIEW -> NOTHING transitions ===================================================================== drop view if exists t14; drop table if exists t14_b; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t14_b(a int); create view t14 as select * from t14_b; prepare stmt from 'select * from t14'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop view t14; +set @expected = @expected + 1; execute stmt; ERROR 42S02: Table 'test.t14' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 +set @expected = @expected + 1; execute stmt; ERROR 42S02: Table 'test.t14' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t14_b; ===================================================================== Testing 15: VIEW -> TABLE transitions ===================================================================== drop view if exists t15; drop table if exists t15_b; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t15_b(a int); create view t15 as select * from t15_b; prepare stmt from 'select * from t15'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop view t15; create table t15(a int); +set @expected = @expected + 1; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t15_b; drop table t15; ===================================================================== @@ -907,38 +1410,60 @@ Testing 16: VIEW -> TEMPORARY TABLE transitions ===================================================================== drop view if exists t16; drop table if exists t16_b; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t16_b(a int); create view t16 as select * from t16_b; prepare stmt from 'select * from t16'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop view t16; create temporary table t16(a int); +set @expected = @expected + 1; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t16_b; drop temporary table t16; ===================================================================== @@ -946,9 +1471,6 @@ Testing 17: VIEW -> VIEW (DDL) transitions ===================================================================== drop view if exists t17; drop table if exists t17_b; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t17_b(a int); insert into t17_b values (10), (20), (30); create view t17 as select a, 2*a as b, 3*a as c from t17_b; @@ -963,44 +1485,69 @@ a b c 10 20 30 20 40 60 30 60 90 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a b c 10 20 30 20 40 60 30 60 90 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop view t17; -create view t17 as select a, 2*a as b, 10*a as c from t17_b; +create view t17 as select a, 2*a as b, 5*a as c from t17_b; select * from t17; a b c -10 20 100 -20 40 200 -30 60 300 +10 20 50 +20 40 100 +30 60 150 +set @expected = @expected + 1; execute stmt; a b c -10 20 100 -20 40 200 -30 60 300 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +10 20 50 +20 40 100 +30 60 150 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a b c -10 20 100 -20 40 200 -30 60 300 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +10 20 50 +20 40 100 +30 60 150 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t17_b; drop view t17; ===================================================================== @@ -1013,9 +1560,6 @@ drop view if exists t18_view; drop view if exists t18_table; drop function if exists view_func; drop view if exists view_view; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t18(a int); insert into t18 values (1), (2), (3); create function view_func(x int) returns int @@ -1031,117 +1575,192 @@ a b 1 2 2 3 3 4 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt_func; a b 1 2 2 3 3 4 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop function view_func; create function view_func(x int) returns int return x*x; +set @expected = @expected + 1; execute stmt_func; a b 1 1 2 4 3 9 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt_func; a b 1 1 2 4 3 9 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 prepare stmt_view from 'select * from t18_view'; execute stmt_view; a b 1 view v1 2 view v1 3 view v1 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt_view; a b 1 view v1 2 view v1 3 view v1 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop view view_view; create view view_view as select "view v2" as reason from dual; +set @expected = @expected + 1; execute stmt_view; a b 1 view v2 2 view v2 3 view v2 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt_view; a b 1 view v2 2 view v2 3 view v2 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 prepare stmt_table from 'select * from t18_table'; execute stmt_table; a 1 2 3 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt_table; a 1 2 3 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t18 add column comments varchar(50) default NULL; +set @expected = @expected + 1; execute stmt_table; a 1 2 3 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt_table; a 1 2 3 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t18; drop table t18_dependent_table; drop view t18_func; @@ -1153,9 +1772,6 @@ drop view view_view; Testing 19: Special tables (INFORMATION_SCHEMA) ===================================================================== drop procedure if exists proc_19; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; prepare stmt from 'select ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE from INFORMATION_SCHEMA.ROUTINES where @@ -1164,115 +1780,178 @@ create procedure proc_19() select "hi there"; execute stmt; ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE test proc_19 PROCEDURE -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE test proc_19 PROCEDURE -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop procedure proc_19; create procedure proc_19() select "hi there, again"; execute stmt; ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE test proc_19 PROCEDURE -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE test proc_19 PROCEDURE -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop procedure proc_19; ===================================================================== Testing 20: Special tables (log tables) ===================================================================== -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; prepare stmt from 'select * from mysql.general_log where argument=\'IMPOSSIBLE QUERY STRING\''; execute stmt; event_time user_host thread_id server_id command_type argument -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; event_time user_host thread_id server_id command_type argument -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; event_time user_host thread_id server_id command_type argument -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; event_time user_host thread_id server_id command_type argument -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 ===================================================================== Testing 21: Special tables (system tables) ===================================================================== drop procedure if exists proc_21; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; prepare stmt from 'select type, db, name from mysql.proc where name=\'proc_21\''; create procedure proc_21() select "hi there"; execute stmt; type db name PROCEDURE test proc_21 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; type db name PROCEDURE test proc_21 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop procedure proc_21; create procedure proc_21() select "hi there, again"; execute stmt; type db name PROCEDURE test proc_21 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; type db name PROCEDURE test proc_21 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop procedure proc_21; ===================================================================== Testing 22: Special tables (views temp tables) ===================================================================== drop table if exists t22_b; drop view if exists t22; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t22_b(a int); create algorithm=temptable view t22 as select a*a as a2 from t22_b; show create view t22; @@ -1285,19 +1964,31 @@ a2 1 4 9 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a2 1 4 9 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 insert into t22_b values (4), (5), (6); execute stmt; a2 @@ -1307,10 +1998,16 @@ a2 16 25 36 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a2 1 @@ -1319,10 +2016,16 @@ a2 16 25 36 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t22_b; drop view t22; ===================================================================== @@ -1330,9 +2033,6 @@ Testing 23: Special tables (internal join tables) ===================================================================== drop table if exists t23_a; drop table if exists t23_b; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t23_a(a int); create table t23_b(b int); prepare stmt from 'select * from t23_a join t23_b'; @@ -1349,10 +2049,16 @@ a b 1 30 2 30 3 30 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a b 1 10 @@ -1364,10 +2070,16 @@ a b 1 30 2 30 3 30 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 insert into t23_a values (4); insert into t23_b values (40); execute stmt; @@ -1388,10 +2100,16 @@ a b 2 40 3 40 4 40 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a b 1 10 @@ -1410,45 +2128,72 @@ a b 2 40 3 40 4 40 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t23_a; drop table t23_b; ===================================================================== Testing 24: Special statements ===================================================================== drop table if exists t24_alter; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t24_alter(a int); prepare stmt from 'alter table t24_alter add column b int'; execute stmt; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t24_alter; create table t24_alter(a1 int, a2 int); execute stmt; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t24_alter drop column b; execute stmt; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t24_alter drop column b; execute stmt; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t24_alter; drop table if exists t24_repair; create table t24_repair(a int); @@ -1457,36 +2202,60 @@ prepare stmt from 'repair table t24_repair'; execute stmt; Table Op Msg_type Msg_text test.t24_repair repair status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t24_repair; create table t24_repair(a1 int, a2 int); insert into t24_repair values (1, 10), (2, 20), (3, 30); execute stmt; Table Op Msg_type Msg_text test.t24_repair repair status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t24_repair add column b varchar(50) default NULL; execute stmt; Table Op Msg_type Msg_text test.t24_repair repair status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t24_repair drop column b; execute stmt; Table Op Msg_type Msg_text test.t24_repair repair status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t24_repair; drop table if exists t24_analyze; create table t24_analyze(a int); @@ -1495,36 +2264,60 @@ prepare stmt from 'analyze table t24_analyze'; execute stmt; Table Op Msg_type Msg_text test.t24_analyze analyze status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t24_analyze; create table t24_analyze(a1 int, a2 int); insert into t24_analyze values (1, 10), (2, 20), (3, 30); execute stmt; Table Op Msg_type Msg_text test.t24_analyze analyze status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t24_analyze add column b varchar(50) default NULL; execute stmt; Table Op Msg_type Msg_text test.t24_analyze analyze status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t24_analyze drop column b; execute stmt; Table Op Msg_type Msg_text test.t24_analyze analyze status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t24_analyze; drop table if exists t24_optimize; create table t24_optimize(a int); @@ -1533,176 +2326,308 @@ prepare stmt from 'optimize table t24_optimize'; execute stmt; Table Op Msg_type Msg_text test.t24_optimize optimize status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t24_optimize; create table t24_optimize(a1 int, a2 int); insert into t24_optimize values (1, 10), (2, 20), (3, 30); execute stmt; Table Op Msg_type Msg_text test.t24_optimize optimize status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t24_optimize add column b varchar(50) default NULL; execute stmt; Table Op Msg_type Msg_text test.t24_optimize optimize status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t24_optimize drop column b; execute stmt; Table Op Msg_type Msg_text test.t24_optimize optimize status OK -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t24_optimize; drop procedure if exists changing_proc; prepare stmt from 'show create procedure changing_proc'; execute stmt; ERROR 42000: PROCEDURE changing_proc does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; ERROR 42000: PROCEDURE changing_proc does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 create procedure changing_proc() begin end; execute stmt; Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation changing_proc CREATE DEFINER=`root`@`localhost` PROCEDURE `changing_proc`() begin end latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation changing_proc CREATE DEFINER=`root`@`localhost` PROCEDURE `changing_proc`() begin end latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop procedure changing_proc; create procedure changing_proc(x int, y int) begin end; execute stmt; Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation changing_proc CREATE DEFINER=`root`@`localhost` PROCEDURE `changing_proc`(x int, y int) begin end latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation changing_proc CREATE DEFINER=`root`@`localhost` PROCEDURE `changing_proc`(x int, y int) begin end latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop procedure changing_proc; execute stmt; ERROR 42000: PROCEDURE changing_proc does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; ERROR 42000: PROCEDURE changing_proc does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop function if exists changing_func; prepare stmt from 'show create function changing_func'; execute stmt; ERROR 42000: FUNCTION changing_func does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; ERROR 42000: FUNCTION changing_func does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 create function changing_func() returns int return 0; execute stmt; Function sql_mode Create Function character_set_client collation_connection Database Collation changing_func CREATE DEFINER=`root`@`localhost` FUNCTION `changing_func`() RETURNS int(11) return 0 latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; Function sql_mode Create Function character_set_client collation_connection Database Collation changing_func CREATE DEFINER=`root`@`localhost` FUNCTION `changing_func`() RETURNS int(11) return 0 latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop function changing_func; create function changing_func(x int, y int) returns int return x+y; execute stmt; Function sql_mode Create Function character_set_client collation_connection Database Collation changing_func CREATE DEFINER=`root`@`localhost` FUNCTION `changing_func`(x int, y int) RETURNS int(11) return x+y latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; Function sql_mode Create Function character_set_client collation_connection Database Collation changing_func CREATE DEFINER=`root`@`localhost` FUNCTION `changing_func`(x int, y int) RETURNS int(11) return x+y latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop function changing_func; execute stmt; ERROR 42000: FUNCTION changing_func does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; ERROR 42000: FUNCTION changing_func does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table if exists t24_trigger; create table t24_trigger(a int); prepare stmt from 'show create trigger t24_bi;'; execute stmt; ERROR HY000: Trigger does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; ERROR HY000: Trigger does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 create trigger t24_bi before insert on t24_trigger for each row begin set @message= "t24_bi"; @@ -1714,239 +2639,427 @@ t24_bi CREATE DEFINER=`root`@`localhost` trigger t24_bi before insert on t24_tr begin set @message= "t24_bi"; end latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation t24_bi CREATE DEFINER=`root`@`localhost` trigger t24_bi before insert on t24_trigger for each row begin set @message= "t24_bi"; end latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop trigger t24_bi; create trigger t24_bi before insert on t24_trigger for each row begin set @message= "t24_bi (2)"; end $$ +set @expected = @expected + 1; execute stmt; Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation t24_bi CREATE DEFINER=`root`@`localhost` trigger t24_bi before insert on t24_trigger for each row begin set @message= "t24_bi (2)"; end latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation t24_bi CREATE DEFINER=`root`@`localhost` trigger t24_bi before insert on t24_trigger for each row begin set @message= "t24_bi (2)"; end latin1 latin1_swedish_ci latin1_swedish_ci -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop trigger t24_bi; execute stmt; ERROR HY000: Trigger does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; ERROR HY000: Trigger does not exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t24_trigger; ===================================================================== Testing 25: Testing the strength of TABLE_SHARE version ===================================================================== drop table if exists t25_num_col; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t25_num_col(a int); -prepare stmt from 'select * from t25_num_col'; +prepare stmt from 'select a from t25_num_col'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t25_num_col add column b varchar(50) default NULL; +set @expected = @expected + 1; execute stmt; -a b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +a +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; -a b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +a +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t25_num_col; drop table if exists t25_col_name; create table t25_col_name(a int); prepare stmt from 'select * from t25_col_name'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t25_col_name change a b int; +set @expected = @expected + 1; execute stmt; -b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +ERROR HY000: Prepared statement result set has changed, rebind needed +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 +set @expected = @expected + 1; execute stmt; -b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +ERROR HY000: Prepared statement result set has changed, rebind needed +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t25_col_name; drop table if exists t25_col_type; create table t25_col_type(a int); prepare stmt from 'select * from t25_col_type'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t25_col_type change a a varchar(10); +set @expected = @expected + 1; execute stmt; -a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -3 +ERROR HY000: Prepared statement result set has changed, rebind needed +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 +set @expected = @expected + 1; execute stmt; -a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -3 +ERROR HY000: Prepared statement result set has changed, rebind needed +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t25_col_type; drop table if exists t25_col_type_length; create table t25_col_type_length(a varchar(10)); prepare stmt from 'select * from t25_col_type_length'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -3 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -3 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t25_col_type_length change a a varchar(20); +set @expected = @expected + 1; execute stmt; -a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -4 +ERROR HY000: Prepared statement result set has changed, rebind needed +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 +set @expected = @expected + 1; execute stmt; -a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -4 +ERROR HY000: Prepared statement result set has changed, rebind needed +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t25_col_type_length; drop table if exists t25_col_null; create table t25_col_null(a varchar(10)); prepare stmt from 'select * from t25_col_null'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -4 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -4 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t25_col_null change a a varchar(10) NOT NULL; +set @expected = @expected + 1; execute stmt; -a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +ERROR HY000: Prepared statement result set has changed, rebind needed +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 +set @expected = @expected + 1; execute stmt; -a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +ERROR HY000: Prepared statement result set has changed, rebind needed +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t25_col_null; drop table if exists t25_col_default; create table t25_col_default(a int, b int DEFAULT 10); prepare stmt from 'insert into t25_col_default(a) values (?)'; set @val=1; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 set @val=2; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t25_col_default change b b int DEFAULT 20; set @val=3; +set @expected = @expected + 1; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 set @val=4; execute stmt using @val; -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 select * from t25_col_default; a b 1 10 @@ -1959,29 +3072,54 @@ create table t25_index(a varchar(10)); prepare stmt from 'select * from t25_index'; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -5 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 create index i1 on t25_index(a); +set @expected = @expected + 1; execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -6 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -6 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t25_index; drop table if exists t25_index_unique; create table t25_index_unique(a varchar(10), b varchar(10)); @@ -1996,16 +3134,28 @@ t25_index_unique CREATE TABLE `t25_index_unique` ( prepare stmt from 'select * from t25_index_unique'; execute stmt; a b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -6 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -6 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 alter table t25_index_unique drop index i1; create unique index i1 on t25_index_unique(a, b); show create table t25_index_unique; @@ -2015,18 +3165,31 @@ t25_index_unique CREATE TABLE `t25_index_unique` ( `b` varchar(10) DEFAULT NULL, UNIQUE KEY `i1` (`a`,`b`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 +set @expected = @expected + 1; execute stmt; a b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -7 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a b -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -7 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t25_index_unique; ===================================================================== Testing reported bugs @@ -2035,9 +3198,6 @@ drop table if exists table_12093; drop function if exists func_12093; drop function if exists func_12093_unrelated; drop procedure if exists proc_12093; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table table_12093(a int); create function func_12093() returns int @@ -2055,88 +3215,137 @@ prepare stmt_sp from 'call proc_12093(func_12093())'; execute stmt_sf; func_12093() 0 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt_sp; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop function func_12093_unrelated; drop procedure proc_12093_unrelated; execute stmt_sf; func_12093() 0 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt_sp; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt_sf; func_12093() 0 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt_sp; a -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 deallocate prepare stmt_sf; deallocate prepare stmt_sp; drop table table_12093; drop function func_12093; drop procedure proc_12093; drop function if exists func_21294; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create function func_21294() returns int return 10; prepare stmt from "select func_21294()"; execute stmt; func_21294() 10 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop function func_21294; create function func_21294() returns int return 10; execute stmt; func_21294() 10 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop function func_21294; create function func_21294() returns int return 20; +set @expected = @expected + 1; execute stmt; func_21294() 20 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 deallocate prepare stmt; drop function func_21294; drop table if exists t_27420_100; drop table if exists t_27420_101; drop view if exists v_27420; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t_27420_100(a int); insert into t_27420_100 values (1), (2); create table t_27420_101(a int); @@ -2149,35 +3358,52 @@ execute stmt; X Y 1 1 2 2 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop view v_27420; create table v_27420(X int, Y int); +set @expected = @expected + 1; execute stmt; X Y -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table v_27420; create table v_27420 (a int, b int, filler char(200)); +set @expected = @expected + 1; execute stmt; -a b filler -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -2 +ERROR HY000: Prepared statement result set has changed, rebind needed +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 deallocate prepare stmt; drop table t_27420_100; drop table t_27420_101; drop table v_27420; drop table if exists t_27430_1; drop table if exists t_27430_2; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t_27430_1 (a int not null, oref int not null, key(a)); insert into t_27430_1 values (1, 1), @@ -2199,20 +3425,32 @@ oref a Z 2 2 0 3 1234 0 4 1234 0 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; oref a Z 1 1 1 2 2 0 3 1234 0 4 1234 0 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table t_27430_1, t_27430_2; create table t_27430_1 (a int, oref int, key(a)); insert into t_27430_1 values @@ -2227,35 +3465,38 @@ insert into t_27430_2 values (2,2), (NULL, 3), (NULL, 4); +set @expected = @expected + 1; execute stmt; -oref a Z -1 1 1 -2 2 0 -3 NULL NULL -4 NULL 0 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +ERROR HY000: Prepared statement result set has changed, rebind needed +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 +set @expected = @expected + 1; execute stmt; -oref a Z -1 1 1 -2 2 0 -3 NULL NULL -4 NULL 0 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +ERROR HY000: Prepared statement result set has changed, rebind needed +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 deallocate prepare stmt; drop table t_27430_1; drop table t_27430_2; drop table if exists t_27690_1; drop view if exists v_27690_1; drop table if exists v_27690_2; -SELECT VARIABLE_VALUE from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' -into @base_count ; create table t_27690_1 (a int, b int); insert into t_27690_1 values (1,1),(2,2); create table v_27690_1 as select * from t_27690_1; @@ -2267,34 +3508,59 @@ a b a b 2 2 1 1 1 1 2 2 2 2 2 2 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a b a b 1 1 1 1 2 2 1 1 1 1 2 2 2 2 2 2 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 drop table v_27690_1; execute stmt; ERROR 42S02: Table 'test.v_27690_1' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; ERROR 42S02: Table 'test.v_27690_1' doesn't exist -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -0 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 create view v_27690_1 as select A.a, A.b from t_27690_1 A, t_27690_1 B; +set @expected = @expected + 1; execute stmt; a b a b 1 1 1 1 @@ -2305,10 +3571,16 @@ a b a b 2 2 2 2 1 1 2 2 2 2 2 2 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 execute stmt; a b a b 1 1 1 1 @@ -2319,10 +3591,16 @@ a b a b 2 2 2 2 1 1 2 2 2 2 2 2 -SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; -REPREPARED -1 +SELECT CASE (VARIABLE_VALUE - @base_count - @expected) +WHEN 0 THEN "PASSED" + ELSE "FAILED" + END +AS `CHECK`, +(VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS +where variable_name='COM_STMT_REPREPARE' ; +CHECK OFFSET +PASSED 0 deallocate prepare stmt; drop table t_27690_1; drop view v_27690_1; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index ff32d2a1512..c5fcb833933 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -1427,4 +1427,9 @@ DROP FUNCTION f1; DROP TABLE t1; DROP EVENT ev1; SHOW TABLE TYPES; +CREATE USER test_u@localhost; +GRANT PROCESS ON *.* TO test_u@localhost; +SHOW ENGINE MYISAM MUTEX; +SHOW ENGINE MYISAM STATUS; +DROP USER test_u@localhost; End of 5.1 tests diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index c33c378340e..bc2ab13fe5f 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -1627,3 +1627,14 @@ end loop label1; end loop; end| ERROR 42000: End-label label1 without match +drop procedure if exists p1; +create procedure p1() +begin +create table t1 (a int) type=MyISAM; +drop table t1; +end| +Warnings: +Warning 1287 The syntax 'TYPE=storage_engine' is deprecated and will be removed in MySQL 5.2. Please use 'ENGINE=storage_engine' instead +call p1(); +call p1(); +drop procedure p1; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 50ece83b258..a68be67a8e0 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6963,6 +6963,22 @@ END latin1 latin1_swedish_ci latin1_swedish_ci DROP FUNCTION f1; +drop procedure if exists p; +set @old_mode= @@sql_mode; +set @@sql_mode= pow(2,32)-1; +select @@sql_mode into @full_mode; +create procedure p() begin end; +call p(); +select @@sql_mode; +@@sql_mode +REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,?,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH +set @@sql_mode= @old_mode; +select replace(@full_mode, '?', 'NOT_USED') into @full_mode; +select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode; +select name from mysql.proc where name = 'p' and sql_mode = @full_mode; +name +p +drop procedure p; # ------------------------------------------------------------------ # -- End of 5.1 tests # ------------------------------------------------------------------ diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result index d1aff0fa657..171b53ebf09 100644 --- a/mysql-test/r/system_mysql_db.result +++ b/mysql-test/r/system_mysql_db.result @@ -201,7 +201,7 @@ proc CREATE TABLE `proc` ( `definer` char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', - `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') NOT NULL DEFAULT '', + `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '', `comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', `character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, `collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, @@ -226,7 +226,7 @@ event CREATE TABLE `event` ( `ends` datetime DEFAULT NULL, `status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED', `on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP', - `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') NOT NULL DEFAULT '', + `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '', `comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', `originator` int(10) NOT NULL, `time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', diff --git a/mysql-test/suite/binlog/r/binlog_base64_flag.result b/mysql-test/suite/binlog/r/binlog_base64_flag.result index aa801346d9f..8e5d7def823 100644 --- a/mysql-test/suite/binlog/r/binlog_base64_flag.result +++ b/mysql-test/suite/binlog/r/binlog_base64_flag.result @@ -40,8 +40,13 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -create table t1 (a int) engine= myisam/*!*/; +create table t1 (a int) engine= myisam +/*!*/; # at 203 +DELIMITER ; +# End of log file +ROLLBACK /* added by mysqlbinlog */; +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; ==== Test non-matching FD event and Row event ==== BINLOG ' 4CdYRw8BAAAAYgAAAGYAAAAAAAQANS4xLjE1LW5kYi02LjEuMjQtZGVidWctbG9nAAAAAAAAAAAA diff --git a/mysql-test/suite/binlog/r/binlog_old_versions.result b/mysql-test/suite/binlog/r/binlog_old_versions.result index a514f9278a6..77289252b4c 100644 --- a/mysql-test/suite/binlog/r/binlog_old_versions.result +++ b/mysql-test/suite/binlog/r/binlog_old_versions.result @@ -29,6 +29,16 @@ SELECT COUNT(*) FROM t3; COUNT(*) 17920 DROP TABLE t1, t2, t3; +==== Read binlog from version 4.1 ==== +SELECT * FROM t1 ORDER BY a; +a b +0 last_insert_id +4 four +190243 random +SELECT COUNT(*) FROM t3; +COUNT(*) +17920 +DROP TABLE t1, t3; ==== Read binlog from alcatel tree (mysql-5.1-wl2325-5.0-drop6) ==== SELECT * FROM t1 ORDER BY a; a b diff --git a/mysql-test/suite/binlog/r/binlog_row_binlog.result b/mysql-test/suite/binlog/r/binlog_row_binlog.result index 6c5c149d48e..8da441d5865 100644 --- a/mysql-test/suite/binlog/r/binlog_row_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result @@ -1072,6 +1072,22 @@ master-bin.000001 30301 Rotate 1 30345 master-bin.000002;pos=4 drop table t1; set global binlog_cache_size=@bcs; set session autocommit = @ac; +drop table if exists t1; +reset master; +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +execute stmt using @a, @b; +deallocate prepare stmt; +drop table t1; +show binlog events from 0; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 +master-bin.000001 106 Query 1 227 use `test`; create table t1 (a bigint unsigned, b bigint(20) unsigned) +master-bin.000001 227 Table_map 1 269 table_id: # (test.t1) +master-bin.000001 269 Write_rows 1 315 table_id: # flags: STMT_END_F +master-bin.000001 315 Query 1 391 use `test`; drop table t1 End of 5.0 tests reset master; create table t1 (id tinyint auto_increment primary key); diff --git a/mysql-test/suite/binlog/r/binlog_stm_binlog.result b/mysql-test/suite/binlog/r/binlog_stm_binlog.result index 80908e6b450..54a2ceda9b3 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result @@ -579,6 +579,21 @@ master-bin.000001 36593 Rotate 1 36637 master-bin.000002;pos=4 drop table t1; set global binlog_cache_size=@bcs; set session autocommit = @ac; +drop table if exists t1; +reset master; +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +execute stmt using @a, @b; +deallocate prepare stmt; +drop table t1; +show binlog events from 0; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 +master-bin.000001 106 Query 1 227 use `test`; create table t1 (a bigint unsigned, b bigint(20) unsigned) +master-bin.000001 227 Query 1 351 use `test`; insert into t1 values (9999999999999999,14632475938453979136) +master-bin.000001 351 Query 1 427 use `test`; drop table t1 End of 5.0 tests reset master; create table t1 (id tinyint auto_increment primary key); diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_4_1.000001 b/mysql-test/suite/binlog/std_data/binlog_old_version_4_1.000001 new file mode 100644 index 00000000000..66db9668d46 Binary files /dev/null and b/mysql-test/suite/binlog/std_data/binlog_old_version_4_1.000001 differ diff --git a/mysql-test/suite/binlog/std_data/binlog-bug32407.000001 b/mysql-test/suite/binlog/std_data/bug32407.001 similarity index 100% rename from mysql-test/suite/binlog/std_data/binlog-bug32407.000001 rename to mysql-test/suite/binlog/std_data/bug32407.001 diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_5_1-telco.000001 b/mysql-test/suite/binlog/std_data/ver_5_1-telco.001 similarity index 100% rename from mysql-test/suite/binlog/std_data/binlog_old_version_5_1-telco.000001 rename to mysql-test/suite/binlog/std_data/ver_5_1-telco.001 diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_row.000001 b/mysql-test/suite/binlog/std_data/ver_5_1-wl2325_r.001 similarity index 100% rename from mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_row.000001 rename to mysql-test/suite/binlog/std_data/ver_5_1-wl2325_r.001 diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_stm.000001 b/mysql-test/suite/binlog/std_data/ver_5_1-wl2325_s.001 similarity index 100% rename from mysql-test/suite/binlog/std_data/binlog_old_version_5_1-wl2325_stm.000001 rename to mysql-test/suite/binlog/std_data/ver_5_1-wl2325_s.001 diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_5_1_17.000001 b/mysql-test/suite/binlog/std_data/ver_5_1_17.001 similarity index 100% rename from mysql-test/suite/binlog/std_data/binlog_old_version_5_1_17.000001 rename to mysql-test/suite/binlog/std_data/ver_5_1_17.001 diff --git a/mysql-test/suite/binlog/std_data/binlog_old_version_5_1_23.000001 b/mysql-test/suite/binlog/std_data/ver_5_1_23.001 similarity index 100% rename from mysql-test/suite/binlog/std_data/binlog_old_version_5_1_23.000001 rename to mysql-test/suite/binlog/std_data/ver_5_1_23.001 diff --git a/mysql-test/suite/binlog/t/binlog_base64_flag.test b/mysql-test/suite/binlog/t/binlog_base64_flag.test index 32319460ab8..01f98b8a134 100644 --- a/mysql-test/suite/binlog/t/binlog_base64_flag.test +++ b/mysql-test/suite/binlog/t/binlog_base64_flag.test @@ -6,6 +6,10 @@ # See also BUG#32407. +# BINLOG statement does not work in embedded mode. +source include/not_embedded.inc; + + # Test to show BUG#32407. This reads a binlog created with the # mysql-5.1-telco-6.1 tree, specifically at the tag # mysql-5.1.15-ndb-6.1.23, and applies it to the database. The test @@ -15,7 +19,7 @@ # The binlog contains row events equivalent to: # CREATE TABLE t1 (a int) engine = myisam # INSERT INTO t1 VALUES (1), (1) -exec $MYSQL_BINLOG suite/binlog/std_data/binlog-bug32407.000001 | $MYSQL; +exec $MYSQL_BINLOG suite/binlog/std_data/bug32407.001 | $MYSQL; # The above line should succeed and t1 should contain two ones select * from t1; @@ -68,7 +72,7 @@ select * from t1; # mysqlbinlog should fail --replace_regex /#[0-9][0-9][0-9][0-9][0-9][0-9] .*/#/ error 1; -exec $MYSQL_BINLOG --base64-output=never suite/binlog/std_data/binlog-bug32407.000001; +exec $MYSQL_BINLOG --base64-output=never suite/binlog/std_data/bug32407.001; # the above line should output the query log event and then stop @@ -78,7 +82,7 @@ exec $MYSQL_BINLOG --base64-output=never suite/binlog/std_data/binlog-bug32407.0 --echo ==== Test non-matching FD event and Row event ==== # This is the Format_description_log_event from -# binlog-bug32407.000001, encoded in base64. It contains only the old +# bug32407.001, encoded in base64. It contains only the old # row events (number of event types is 22) BINLOG ' 4CdYRw8BAAAAYgAAAGYAAAAAAAQANS4xLjE1LW5kYi02LjEuMjQtZGVidWctbG9nAAAAAAAAAAAA diff --git a/mysql-test/suite/binlog/t/binlog_killed.test b/mysql-test/suite/binlog/t/binlog_killed.test index e5f7288b17c..ab8a8cd59bd 100644 --- a/mysql-test/suite/binlog/t/binlog_killed.test +++ b/mysql-test/suite/binlog/t/binlog_killed.test @@ -39,7 +39,7 @@ connection con2; reap; let $rows= `select count(*) from t2 /* must be 2 or 0 */`; ---exec $MYSQL_BINLOG --start-position=134 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog +--exec $MYSQL_BINLOG --force-if-open --start-position=134 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval select (@a:=load_file("$MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog")) @@ -250,7 +250,7 @@ source include/show_binlog_events.inc; # a proof the query is binlogged with an error ---exec $MYSQL_BINLOG --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog +--exec $MYSQL_BINLOG --force-if-open --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval select (@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog")) @@ -296,7 +296,7 @@ source include/show_binlog_events.inc; # a proof the query is binlogged with an error ---exec $MYSQL_BINLOG --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog +--exec $MYSQL_BINLOG --force-if-open --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval select (@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog")) diff --git a/mysql-test/suite/binlog/t/binlog_killed_simulate.test b/mysql-test/suite/binlog/t/binlog_killed_simulate.test index 2121a90dc8c..cb3b5a6e827 100644 --- a/mysql-test/suite/binlog/t/binlog_killed_simulate.test +++ b/mysql-test/suite/binlog/t/binlog_killed_simulate.test @@ -23,7 +23,7 @@ update t1 set a=2 /* will be "killed" after work has been done */; #todo: introduce a suite private macro that provides numeric values # for some constants like the offset of the first real event # that is different between severs versions. ---exec $MYSQL_BINLOG --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog +--exec $MYSQL_BINLOG --force-if-open --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval select (@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog")) @@ -51,7 +51,7 @@ load data infile '../std_data_ln/rpl_loaddata.dat' into table t2 /* will be "kil source include/show_binlog_events.inc; ---exec $MYSQL_BINLOG --start-position=98 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog +--exec $MYSQL_BINLOG --force-if-open --start-position=98 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval select (@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog")) diff --git a/mysql-test/suite/binlog/t/binlog_old_versions.test b/mysql-test/suite/binlog/t/binlog_old_versions.test index 2d56ebd588d..0ccea406a82 100644 --- a/mysql-test/suite/binlog/t/binlog_old_versions.test +++ b/mysql-test/suite/binlog/t/binlog_old_versions.test @@ -31,7 +31,7 @@ DROP TABLE IF EXISTS t1, t2, t3; --echo ==== Read modern binlog (version 5.1.23) ==== # Read binlog. ---exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1_23.000001 | $MYSQL --local-infile=1 +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1_23.001 | $MYSQL --local-infile=1 # Show result. SELECT * FROM t1 ORDER BY a; SELECT * FROM t2 ORDER BY a; @@ -43,7 +43,7 @@ DROP TABLE t1, t2, t3; --echo ==== Read binlog from version 5.1.17 ==== # Read binlog. ---exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1_17.000001 | $MYSQL --local-infile=1 +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1_17.001 | $MYSQL --local-infile=1 # Show result. SELECT * FROM t1 ORDER BY a; SELECT * FROM t2 ORDER BY a; @@ -52,6 +52,21 @@ SELECT COUNT(*) FROM t3; DROP TABLE t1, t2, t3; +--echo ==== Read binlog from version 4.1 ==== + +# In this version, neither row-based binlogging nor Xid events +# existed, so the binlog was generated without the "row-based tests" +# part and the "get xid event" part, and it does not create table t2. + +# Read binlog. +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_4_1.000001 | $MYSQL --local-infile=1 +# Show result. +SELECT * FROM t1 ORDER BY a; +SELECT COUNT(*) FROM t3; +# Reset. +DROP TABLE t1, t3; + + --echo ==== Read binlog from alcatel tree (mysql-5.1-wl2325-5.0-drop6) ==== # In this version, it was not possible to switch between row-based and @@ -60,9 +75,9 @@ DROP TABLE t1, t2, t3; # replication. # Read rbr binlog. ---exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1-wl2325_row.000001 | $MYSQL --local-infile=1 +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1-wl2325_r.001 | $MYSQL --local-infile=1 # Read stm binlog. ---exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1-wl2325_stm.000001 | $MYSQL --local-infile=1 +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1-wl2325_s.001 | $MYSQL --local-infile=1 # Show result. SELECT * FROM t1 ORDER BY a; SELECT * FROM t2 ORDER BY a; @@ -74,7 +89,7 @@ DROP TABLE t1, t2, t3; --echo ==== Read binlog from ndb tree (mysql-5.1-telco-6.1) ==== # Read binlog. ---exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1-telco.000001 | $MYSQL --local-infile=1 +--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1-telco.001 | $MYSQL --local-infile=1 # Show resulting tablea. SELECT * FROM t1 ORDER BY a; SELECT * FROM t2 ORDER BY a; diff --git a/mysql-test/suite/binlog/t/disabled.def b/mysql-test/suite/binlog/t/disabled.def index c93bc2a158e..a6e73fa31d8 100644 --- a/mysql-test/suite/binlog/t/disabled.def +++ b/mysql-test/suite/binlog/t/disabled.def @@ -10,4 +10,3 @@ # ############################################################################## binlog_multi_engine : Bug#32663 binlog_multi_engine.test fails randomly -binlog_base64_flag : BUG#33247 2007-12-14 Sven: mysqlbinlog does not clean up after itself on termination. When compiled in debug mode, this test generates lots of warnings for memory leaks. diff --git a/mysql-test/suite/bugs/data/rpl_bug12691.dat b/mysql-test/suite/bugs/data/rpl_bug12691.dat new file mode 100644 index 00000000000..de980441c3a --- /dev/null +++ b/mysql-test/suite/bugs/data/rpl_bug12691.dat @@ -0,0 +1,3 @@ +a +b +c diff --git a/mysql-test/suite/bugs/r/rpl_bug12691.result b/mysql-test/suite/bugs/r/rpl_bug12691.result new file mode 100644 index 00000000000..69d5e8009b0 --- /dev/null +++ b/mysql-test/suite/bugs/r/rpl_bug12691.result @@ -0,0 +1,34 @@ +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; + +**** On Master **** +CREATE TABLE t1 (b CHAR(10)); + +**** On Slave **** +STOP SLAVE; + +**** On Master **** +LOAD DATA INFILE FILENAME +SELECT COUNT(*) FROM t1; +COUNT(*) +3 +SHOW BINLOG EVENTS; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Format_desc 1 # Server ver: # +master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1 (b CHAR(10)) +master-bin.000001 # Begin_load_query 1 # ;file_id=#;block_len=# +master-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE FILENAME ;file_id=# + +**** On Slave **** +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +START SLAVE; +SELECT COUNT(*) FROM t1; +COUNT(*) +0 + +**** On Master **** +DROP TABLE t1; diff --git a/mysql-test/suite/bugs/t/rpl_bug12691.test b/mysql-test/suite/bugs/t/rpl_bug12691.test new file mode 100644 index 00000000000..b29c85584a5 --- /dev/null +++ b/mysql-test/suite/bugs/t/rpl_bug12691.test @@ -0,0 +1,53 @@ +# Bug#12691: Exec_master_log_pos corrupted with SQL_SLAVE_SKIP_COUNTER +# Date: 01/31/2008 +# Added: Serge Kozlov + +--source include/master-slave.inc +--connection master +--source include/have_binlog_format_mixed_or_statement.inc + +--echo +--echo **** On Master **** +CREATE TABLE t1 (b CHAR(10)); +--echo +--echo **** On Slave **** +--sync_slave_with_master +STOP SLAVE; +--source include/wait_for_slave_to_stop.inc + +--connection master + +--echo +--echo **** On Master **** +--exec cp $MYSQL_TEST_DIR/suite/bugs/data/rpl_bug12691.dat $MYSQLTEST_VARDIR/tmp/ +--echo LOAD DATA INFILE FILENAME +--disable_query_log +--eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/rpl_bug12691.dat' INTO TABLE t1 FIELDS TERMINATED BY '|' +--enable_query_log +--remove_file $MYSQLTEST_VARDIR/tmp/rpl_bug12691.dat + +SELECT COUNT(*) FROM t1; + +--replace_column 2 # 5 # +--replace_regex /Server ver: .+/Server ver: #/ /table_id: [0-9]+/table_id: #/ /COMMIT.+xid=[0-9]+.+/#/ /file_id=[0-9]+/file_id=#/ /block_len=[0-9]+/block_len=#/ /'.+'/FILENAME/ +SHOW BINLOG EVENTS; + +--save_master_pos + +--connection slave +--echo +--echo **** On Slave **** +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +START SLAVE; +--source include/wait_for_slave_to_start.inc +--sync_with_master + +SELECT COUNT(*) FROM t1; + +# Clean up +--connection master +--echo +--echo **** On Master **** +DROP TABLE t1; +--sync_slave_with_master + diff --git a/mysql-test/suite/rpl/r/rpl_loaddata_map.result b/mysql-test/suite/rpl/r/rpl_loaddata_map.result index e6ddc1ebedc..7078389c987 100644 --- a/mysql-test/suite/rpl/r/rpl_loaddata_map.result +++ b/mysql-test/suite/rpl/r/rpl_loaddata_map.result @@ -12,13 +12,13 @@ load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2; select count(*) from t2 /* 5 000 */; count(*) 5000 -show binlog events in 'master-bin.000002' from 106; +show binlog events in 'master-bin.000002' from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000002 106 Query 1 # use `test`; create table t2 (id int not null primary key auto_increment) -master-bin.000002 229 Begin_load_query 1 # ;file_id=#;block_len=8192 -master-bin.000002 8444 Append_block 1 # ;file_id=#;block_len=8192 -master-bin.000002 16659 Append_block 1 # ;file_id=#;block_len=7509 -master-bin.000002 24191 Execute_load_query 1 # use `test`; load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2 ;file_id=# +master-bin.000002 # Query # # use `test`; create table t2 (id int not null primary key auto_increment) +master-bin.000002 # Begin_load_query # # ;file_id=#;block_len=# +master-bin.000002 # Append_block # # ;file_id=#;block_len=# +master-bin.000002 # Append_block # # ;file_id=#;block_len=# +master-bin.000002 # Execute_load_query # # use `test`; load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2 ;file_id=# select count(*) from t2 /* 5 000 */; count(*) 5000 diff --git a/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result b/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result index 6859a406b16..e81d4f7454e 100644 --- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result +++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result @@ -26,7 +26,7 @@ ADD x BIT(3) DEFAULT b'011', ADD y BIT(5) DEFAULT b'10101', ADD z BIT(2) DEFAULT b'10'; ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; -ALTER TABLE t1_nodef ADD x INT NOT NULL; +ALTER TABLE t1_nodef ADD x INT NOT NULL, ADD y INT NOT NULL, ADD z INT NOT NULL; ALTER TABLE t2 DROP b; ALTER TABLE t4 MODIFY a FLOAT; ALTER TABLE t5 MODIFY b FLOAT; @@ -393,8 +393,8 @@ INSERT INTO t1_nodef VALUES (1,2); INSERT INTO t1_nodef VALUES (2,4); SET SQL_LOG_BIN=1; **** On Slave **** -INSERT INTO t1_nodef VALUES (1,2,3); -INSERT INTO t1_nodef VALUES (2,4,6); +INSERT INTO t1_nodef VALUES (1,2,3,4,5); +INSERT INTO t1_nodef VALUES (2,4,6,8,10); **** On Master **** UPDATE t1_nodef SET b=2*b WHERE a=1; SELECT * FROM t1_nodef ORDER BY a; @@ -403,9 +403,9 @@ a b 2 4 **** On Slave **** SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 -2 4 6 +a b x y z +1 4 3 4 5 +2 4 6 8 10 **** On Master **** DELETE FROM t1_nodef WHERE a=2; SELECT * FROM t1_nodef ORDER BY a; @@ -413,8 +413,8 @@ a b 1 4 **** On Slave **** SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 +a b x y z +1 4 3 4 5 **** Cleanup **** DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result index 17b2a2f7b52..a6834be5a86 100644 --- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result +++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result @@ -26,7 +26,7 @@ ADD x BIT(3) DEFAULT b'011', ADD y BIT(5) DEFAULT b'10101', ADD z BIT(2) DEFAULT b'10'; ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; -ALTER TABLE t1_nodef ADD x INT NOT NULL; +ALTER TABLE t1_nodef ADD x INT NOT NULL, ADD y INT NOT NULL, ADD z INT NOT NULL; ALTER TABLE t2 DROP b; ALTER TABLE t4 MODIFY a FLOAT; ALTER TABLE t5 MODIFY b FLOAT; @@ -393,8 +393,8 @@ INSERT INTO t1_nodef VALUES (1,2); INSERT INTO t1_nodef VALUES (2,4); SET SQL_LOG_BIN=1; **** On Slave **** -INSERT INTO t1_nodef VALUES (1,2,3); -INSERT INTO t1_nodef VALUES (2,4,6); +INSERT INTO t1_nodef VALUES (1,2,3,4,5); +INSERT INTO t1_nodef VALUES (2,4,6,8,10); **** On Master **** UPDATE t1_nodef SET b=2*b WHERE a=1; SELECT * FROM t1_nodef ORDER BY a; @@ -403,9 +403,9 @@ a b 2 4 **** On Slave **** SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 -2 4 6 +a b x y z +1 4 3 4 5 +2 4 6 8 10 **** On Master **** DELETE FROM t1_nodef WHERE a=2; SELECT * FROM t1_nodef ORDER BY a; @@ -413,8 +413,8 @@ a b 1 4 **** On Slave **** SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 +a b x y z +1 4 3 4 5 **** Cleanup **** DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_map.test b/mysql-test/suite/rpl/t/rpl_loaddata_map.test index 3d6f09844b6..6a8378c8fdc 100644 --- a/mysql-test/suite/rpl/t/rpl_loaddata_map.test +++ b/mysql-test/suite/rpl/t/rpl_loaddata_map.test @@ -7,6 +7,7 @@ # BUG#33413 show binlog events fails if binlog has event size of close # to max_allowed_packet +source include/have_binlog_format_mixed_or_statement.inc; source include/master-slave.inc; source include/have_innodb.inc; source include/have_binlog_format_mixed_or_statement.inc; @@ -35,9 +36,9 @@ select count(*) from t2 /* 5 000 */; # the binglog will show fragmented Append_block events --let $binlog_start=106 ---replace_column 5 # ---replace_regex /\/\* xid=.* \*\//\/* XID *\// /file_id=[0-9]+/file_id=#/ ---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--replace_column 2 # 4 # 5 # +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /file_id=[0-9]+/file_id=#/ /block_len=[0-9]+/block_len=#/ +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR $binlog_start --eval show binlog events in 'master-bin.000002' from $binlog_start diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index dff6bf3fcff..09170cbc4f5 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -1341,4 +1341,48 @@ create table t1 like information_schema.character_sets; show create table t1; drop table t1; +--echo +--echo # -- +--echo # -- Bug#21380: DEFAULT definition not always transfered by CREATE +--echo # -- TABLE/SELECT to the new table. +--echo # -- +--echo + + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +--enable_warnings + +--echo + +CREATE TABLE t1( + c1 INT DEFAULT 12 COMMENT 'column1', + c2 INT NULL COMMENT 'column2', + c3 INT NOT NULL COMMENT 'column3', + c4 VARCHAR(255) CHARACTER SET utf8 NOT NULL DEFAULT 'a', + c5 VARCHAR(255) COLLATE utf8_unicode_ci NULL DEFAULT 'b', + c6 VARCHAR(255)) + COLLATE latin1_bin; + +--echo + +SHOW CREATE TABLE t1; + +--echo + +CREATE TABLE t2 AS SELECT * FROM t1; + +--echo + +SHOW CREATE TABLE t2; + +--echo + +DROP TABLE t2; + +--echo +--echo # -- End of test case for Bug#21380. +--echo + --echo End of 5.1 tests diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 3f9ec52ca36..2cbfb3cf658 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -23,3 +23,4 @@ wait_timeout : Bug#32801 wait_timeout.test fails randomly ctype_create : Bug#32965 main.ctype_create fails status : Bug#32966 main.status fails ps_ddl : Bug#12093 2007-12-14 pending WL#4165 / WL#4166 +query_cache_debug : Bug#34424: query_cache_debug.test leads to valgrind warnings diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test index efdb67349ec..b3b2f37e36f 100644 --- a/mysql-test/t/events_bugs.test +++ b/mysql-test/t/events_bugs.test @@ -935,6 +935,26 @@ DROP USER mysqltest_u1@localhost; --echo ##################################################################### --echo +# +# Bug#32633 Can not create any routine if SQL_MODE=no_engine_substitution +# +# Ensure that when new SQL modes are introduced, they are also added to +# the mysql.event table. +# + +--disable_warnings +drop procedure if exists p; +--enable_warnings +set @old_mode= @@sql_mode; +set @@sql_mode= pow(2,32)-1; +create event e1 on schedule every 1 day do select 1; +select @@sql_mode; +set @@sql_mode= @old_mode; +# Rename SQL modes that differ in name between the server and the table definition. +select replace(@full_mode, '?', 'NOT_USED') into @full_mode; +select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode; +select name from mysql.event where name = 'p' and sql_mode = @full_mode; +drop event e1; ########################################################################### # diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index 16cccd1a1f4..e540ce703a1 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1266,6 +1266,28 @@ DROP DATABASE db27878; use test; DROP TABLE t1; +# +# Bug #33201 Crash occurs when granting update privilege on one column of a view +# +drop table if exists test; +drop function if exists test_function; +drop view if exists v1; +create table test (col1 varchar(30)); +delimiter |; +create function test_function() returns varchar(30) +begin + declare tmp varchar(30); + select col1 from test limit 1 into tmp; + return '1'; +end| +delimiter ;| +create view v1 as select test.* from test where test.col1=test_function(); +grant update (col1) on v1 to 'greg'@'localhost'; +drop user 'greg'@'localhost'; +drop view v1; +drop table test; +drop function test_function; + --echo End of 5.0 tests # @@ -1374,6 +1396,7 @@ GRANT ALL PRIVILEGES ON test.* TO mysqltest_1@localhost; CALL mysqltest1.test(); DROP DATABASE mysqltest1; RENAME TABLE mysql.procs_gone TO mysql.procs_priv; +DROP USER mysqltest_1@localhost; FLUSH PRIVILEGES; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 2a9319fe010..6e76a043645 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1248,4 +1248,26 @@ show events from information_schema; show events where Db= 'information_schema'; use test; +--echo # +--echo # Bug#34166: Server crash in SHOW OPEN TABLES and prelocking +--echo # +--disable_warnings +drop table if exists t1; +drop function if exists f1; +--enable_warnings +create table t1 (a int); +delimiter |; +create function f1() returns int +begin + insert into t1 (a) values (1); + return 0; +end| +delimiter ;| +--disable_result_log +show open tables where f1()=0; +show open tables where f1()=0; +--enable_result_log +drop table t1; +drop function f1; + --echo End of 5.1 tests. diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index 0d36b79df78..06488abb1ae 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -439,4 +439,34 @@ connection default; disconnect flush; drop table t1; +# +# Bug#30331: Table_locks_waited shows inaccurate values +# + +--disable_warnings +drop table if exists t1,t2; +--enable_warnings +create table t1 (a int); +flush status; +lock tables t1 read; +let $tlwa= `show status like 'Table_locks_waited'`; +connect (waiter,localhost,root,,); +connection waiter; +--send insert into t1 values(1); +connection default; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Locked" and info = "insert into t1 values(1)"; +--source include/wait_condition.inc +let $tlwb= `show status like 'Table_locks_waited'`; +unlock tables; +drop table t1; +disconnect waiter; +connection default; +--disable_query_log +eval SET @tlwa= SUBSTRING_INDEX('$tlwa', ' ', -1); +eval SET @tlwb= SUBSTRING_INDEX('$tlwb', ' ', -1); +--enable_query_log +select @tlwa < @tlwb; + --echo End of 5.1 tests diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index d0c8c0b4e38..5856bfff036 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -2101,5 +2101,28 @@ drop table t1; --change_user root,, --change_user root,,test +# ---------------------------------------------------------------------------- +# Test mkdir and rmdir command +# ---------------------------------------------------------------------------- + +mkdir $MYSQLTEST_VARDIR/tmp/testdir; +rmdir $MYSQLTEST_VARDIR/tmp/testdir; + +# Directory already exist +mkdir $MYSQLTEST_VARDIR/tmp/testdir; +--error 1 +mkdir $MYSQLTEST_VARDIR/tmp/testdir; + +# Remove dir with file inside +write_file $MYSQLTEST_VARDIR/tmp/testdir/file1.txt; +hello +EOF +--error 1 +rmdir $MYSQLTEST_VARDIR/tmp/testdir; + +remove_file $MYSQLTEST_VARDIR/tmp/testdir/file1.txt; +rmdir $MYSQLTEST_VARDIR/tmp/testdir; + + --echo End of tests diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index b45d67d8485..a34d41a6dfb 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1821,6 +1821,23 @@ execute stmt using @a; show create table t1; drop table t1; +# +# Bug#33798: prepared statements improperly handle large unsigned ints +# +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (a bigint unsigned, b bigint(20) unsigned); +prepare stmt from "insert into t1 values (?,?)"; +set @a= 9999999999999999; +set @b= 14632475938453979136; +insert into t1 values (@a, @b); +select * from t1 where a = @a and b = @b; +execute stmt using @a, @b; +select * from t1 where a = @a and b = @b; +deallocate prepare stmt; +drop table t1; + --echo End of 5.0 tests. # diff --git a/mysql-test/t/ps_ddl.test b/mysql-test/t/ps_ddl.test index abb6563f052..c824d17063b 100644 --- a/mysql-test/t/ps_ddl.test +++ b/mysql-test/t/ps_ddl.test @@ -55,8 +55,28 @@ let $base_count = SELECT VARIABLE_VALUE from INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' into @base_count ; -let $reprepared = SELECT VARIABLE_VALUE - @base_count AS REPREPARED from -INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; +let $check = SELECT CASE (VARIABLE_VALUE - @base_count - @expected) + WHEN 0 THEN "PASSED" + ELSE "FAILED" + END + AS `CHECK`, + (VARIABLE_VALUE - @base_count - @expected) AS `OFFSET` + from INFORMATION_SCHEMA.SESSION_STATUS + where variable_name='COM_STMT_REPREPARE' ; + +eval $base_count; +set @expected = 0; + +# Maintainer: +# When not expecting a re-prepare, write the test like this: +# execute stmt; +# eval $check; +# +# When expecting a re-prepare, write the test like this: +# set @expected = @expected + 1; +# execute stmt; +# eval $check; +# --echo ===================================================================== --echo Testing 1: NOTHING -> TABLE transitions @@ -66,8 +86,6 @@ INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ; drop table if exists t1; --enable_warnings -eval $base_count; - # can not be tested since prepare failed --error ER_NO_SUCH_TABLE prepare stmt from 'select * from t1'; @@ -92,23 +110,21 @@ prepare stmt from 'select * from t1'; drop table if exists t4; --enable_warnings -eval $base_count; - create table t4(a int); prepare stmt from 'select * from t4'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t4; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; --echo ===================================================================== --echo Testing 5: TABLE -> TABLE (DDL) transitions @@ -118,23 +134,21 @@ eval $reprepared; drop table if exists t5; --enable_warnings -eval $base_count; - create table t5(a int); -prepare stmt from 'select * from t5'; +prepare stmt from 'select a from t5'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; alter table t5 add column (b int); -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t5; @@ -155,17 +169,15 @@ drop table t5; drop table if exists t6; --enable_warnings -eval $base_count; - create table t6(a int); prepare stmt from 'insert into t6(a) value (?)'; set @val=1; execute stmt using @val; -eval $reprepared; +eval $check; set @val=2; execute stmt using @val; -eval $reprepared; +eval $check; # Relevant trigger: execute should reprepare delimiter $$; @@ -178,25 +190,25 @@ delimiter ;$$ set @message="none"; set @val=3; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @val=4; execute stmt using @val; -eval $reprepared; +eval $check; select @message; prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=5; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @message="none"; set @val=6; execute stmt using @val; -eval $reprepared; +eval $check; select @message; # Unrelated trigger: execute can pass of fail, implementation dependent @@ -210,25 +222,26 @@ delimiter ;$$ set @message="none"; set @val=7; +set @expected = @expected + 1; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @message="none"; set @val=8; execute stmt using @val; -eval $reprepared; +eval $check; select @message; prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=9; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @message="none"; set @val=10; execute stmt using @val; -eval $reprepared; +eval $check; select @message; # Relevant trigger: execute should reprepare @@ -243,25 +256,25 @@ delimiter ;$$ set @message="none"; set @val=11; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @val=12; execute stmt using @val; -eval $reprepared; +eval $check; select @message; prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=13; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @message="none"; set @val=14; execute stmt using @val; -eval $reprepared; +eval $check; select @message; # Unrelated trigger: execute can pass of fail, implementation dependent @@ -276,63 +289,62 @@ delimiter ;$$ set @message="none"; set @val=15; +set @expected = @expected + 1; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @message="none"; set @val=16; execute stmt using @val; -eval $reprepared; +eval $check; select @message; prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=17; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @message="none"; set @val=18; execute stmt using @val; -eval $reprepared; +eval $check; select @message; drop trigger t6_bi; set @message="none"; set @val=19; -# safe to re-execute +set @expected = @expected + 1; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @val=20; -# safe to re-execute execute stmt using @val; -eval $reprepared; +eval $check; select @message; prepare stmt from 'insert into t6(a) value (?)'; set @message="none"; set @val=21; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @val=22; execute stmt using @val; -eval $reprepared; +eval $check; select @message; drop trigger t6_bd; set @val=23; -# safe to re-execute +set @expected = @expected + 1; execute stmt using @val; -eval $reprepared; +eval $check; select @message; set @val=24; -# safe to re-execute execute stmt using @val; -eval $reprepared; +eval $check; select @message; select * from t6 order by a; @@ -363,8 +375,6 @@ drop function if exists audit_func; drop view if exists audit_view; --enable_warnings -eval $base_count; - create table t7_proc(a int); create table t7_func(a int); create table t7_view(a int); @@ -400,10 +410,10 @@ create trigger t7_table_trigger_bi before insert on t7_dependent_table prepare stmt_proc from 'insert into t7_proc(a) value (?)'; set @val=101; execute stmt_proc using @val; -eval $reprepared; +eval $check; set @val=102; execute stmt_proc using @val; -eval $reprepared; +eval $check; drop procedure audit_proc; @@ -411,20 +421,21 @@ create procedure audit_proc(a int) insert into t7_audit values (NULL, a, "proc v2"); set @val=103; +set @expected = @expected + 1; execute stmt_proc using @val; -eval $reprepared; +eval $check; set @val=104; execute stmt_proc using @val; -eval $reprepared; +eval $check; prepare stmt_func from 'insert into t7_func(a) value (?)'; set @val=201; execute stmt_func using @val; -eval $reprepared; +eval $check; set @val=202; execute stmt_func using @val; -eval $reprepared; +eval $check; drop function audit_func; @@ -432,19 +443,20 @@ create function audit_func() returns varchar(50) return "func v2"; set @val=203; +set @expected = @expected + 1; execute stmt_func using @val; -eval $reprepared; +eval $check; set @val=204; execute stmt_func using @val; -eval $reprepared; +eval $check; prepare stmt_view from 'insert into t7_view(a) value (?)'; set @val=301; execute stmt_view using @val; -eval $reprepared; +eval $check; set @val=302; execute stmt_view using @val; -eval $reprepared; +eval $check; drop view audit_view; @@ -455,52 +467,53 @@ create view audit_view as select "view v2" as reason from dual; # This is because the table trigger is cached and is not invalidated. set @val=303; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt_view using @val; -eval $reprepared; +eval $check; set @val=304; execute stmt_view using @val; -eval $reprepared; +eval $check; prepare stmt_table from 'insert into t7_table(a) value (?)'; set @val=401; execute stmt_table using @val; -eval $reprepared; +eval $check; set @val=402; execute stmt_table using @val; -eval $reprepared; +eval $check; alter table t7_dependent_table add column comments varchar(100) default NULL; set @val=403; -# REPREPARED +1 +set @expected = @expected + 1; --error ER_WRONG_VALUE_COUNT_ON_ROW execute stmt_table using @val; -eval $reprepared; +eval $check; set @val=404; +set @expected = @expected + 1; --error ER_WRONG_VALUE_COUNT_ON_ROW execute stmt_table using @val; -eval $reprepared; +eval $check; alter table t7_dependent_table drop column comments; set @val=405; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt_table using @val; -eval $reprepared; +eval $check; set @val=406; execute stmt_table using @val; -eval $reprepared; +eval $check; prepare stmt_table_trigger from 'insert into t7_table(a) value (?)'; set @val=501; execute stmt_table_trigger using @val; -eval $reprepared; +eval $check; set @val=502; execute stmt_table_trigger using @val; -eval $reprepared; +eval $check; drop trigger t7_table_trigger_bi; @@ -508,12 +521,12 @@ create trigger t7_table_trigger_bi before insert on t7_dependent_table for each row set NEW.reason="trigger v2"; set @val=503; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt_table_trigger using @val; -eval $reprepared; +eval $check; set @val=504; execute stmt_table_trigger using @val; -eval $reprepared; +eval $check; select * from t7_audit order by new_a; @@ -538,24 +551,22 @@ drop view audit_view; drop table if exists t8; --enable_warnings -eval $base_count; - create table t8(a int); prepare stmt from 'select * from t8'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t8; create temporary table t8(a int); -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t8; @@ -568,25 +579,23 @@ drop table if exists t9; drop table if exists t9_b; --enable_warnings -eval $base_count; - create table t9(a int); create table t9_b(a int); prepare stmt from 'select * from t9'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t9; create view t9 as select * from t9_b; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop view t9; drop table t9_b; @@ -599,23 +608,21 @@ drop table t9_b; drop temporary table if exists t10; --enable_warnings -eval $base_count; - create temporary table t10(a int); prepare stmt from 'select * from t10'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop temporary table t10; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; --echo ===================================================================== --echo Testing 11: TEMPORARY TABLE -> TABLE transitions @@ -626,25 +633,23 @@ drop table if exists t11; drop temporary table if exists t11; --enable_warnings -eval $base_count; - create table t11(a int); insert into t11(a) value (1); create temporary table t11(a int); prepare stmt from 'select * from t11'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop temporary table t11; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; select * from t11; drop table t11; @@ -657,24 +662,22 @@ drop table t11; drop temporary table if exists t12; --enable_warnings -eval $base_count; - create temporary table t12(a int); -prepare stmt from 'select * from t12'; +prepare stmt from 'select a from t12'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop temporary table t12; create temporary table t12(a int, b int); -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; select * from t12; drop table t12; @@ -688,25 +691,23 @@ drop temporary table if exists t13; drop table if exists t13_b; --enable_warnings -eval $base_count; - create temporary table t13(a int); create table t13_b(a int); prepare stmt from 'select * from t13'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop temporary table t13; create view t13 as select * from t13_b; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop view t13; drop table t13_b; @@ -720,26 +721,25 @@ drop view if exists t14; drop table if exists t14_b; --enable_warnings -eval $base_count; - create table t14_b(a int); create view t14 as select * from t14_b; prepare stmt from 'select * from t14'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop view t14; -# REPREPARED +1 +set @expected = @expected + 1; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; +set @expected = @expected + 1; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; drop table t14_b; @@ -752,25 +752,23 @@ drop view if exists t15; drop table if exists t15_b; --enable_warnings -eval $base_count; - create table t15_b(a int); create view t15 as select * from t15_b; prepare stmt from 'select * from t15'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop view t15; create table t15(a int); -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t15_b; drop table t15; @@ -784,25 +782,23 @@ drop view if exists t16; drop table if exists t16_b; --enable_warnings -eval $base_count; - create table t16_b(a int); create view t16 as select * from t16_b; prepare stmt from 'select * from t16'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop view t16; create temporary table t16(a int); -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t16_b; drop temporary table t16; @@ -816,8 +812,6 @@ drop view if exists t17; drop table if exists t17_b; --enable_warnings -eval $base_count; - create table t17_b(a int); insert into t17_b values (10), (20), (30); @@ -826,19 +820,19 @@ select * from t17; prepare stmt from 'select * from t17'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop view t17; -create view t17 as select a, 2*a as b, 10*a as c from t17_b; +create view t17 as select a, 2*a as b, 5*a as c from t17_b; select * from t17; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t17_b; drop view t17; @@ -865,8 +859,6 @@ drop function if exists view_func; drop view if exists view_view; --enable_warnings -eval $base_count; - # TODO: insertable view -> trigger # TODO: insertable view -> trigger -> proc ? @@ -886,47 +878,48 @@ create view t18_table as select * from t18; prepare stmt_func from 'select * from t18_func'; execute stmt_func; -eval $reprepared; +eval $check; execute stmt_func; -eval $reprepared; +eval $check; drop function view_func; create function view_func(x int) returns int return x*x; +set @expected = @expected + 1; execute stmt_func; -eval $reprepared; +eval $check; execute stmt_func; -eval $reprepared; +eval $check; prepare stmt_view from 'select * from t18_view'; execute stmt_view; -eval $reprepared; +eval $check; execute stmt_view; -eval $reprepared; +eval $check; drop view view_view; create view view_view as select "view v2" as reason from dual; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt_view; -eval $reprepared; +eval $check; execute stmt_view; -eval $reprepared; +eval $check; prepare stmt_table from 'select * from t18_table'; execute stmt_table; -eval $reprepared; +eval $check; execute stmt_table; -eval $reprepared; +eval $check; alter table t18 add column comments varchar(50) default NULL; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt_table; -eval $reprepared; +eval $check; execute stmt_table; -eval $reprepared; +eval $check; drop table t18; drop table t18_dependent_table; @@ -944,8 +937,6 @@ drop view view_view; drop procedure if exists proc_19; --enable_warnings -eval $base_count; - # Using a temporary table internally should not confuse the prepared # statement code, and should not raise ER_PS_INVALIDATED errors prepare stmt from @@ -956,17 +947,17 @@ prepare stmt from create procedure proc_19() select "hi there"; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop procedure proc_19; create procedure proc_19() select "hi there, again"; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop procedure proc_19; @@ -974,19 +965,17 @@ drop procedure proc_19; --echo Testing 20: Special tables (log tables) --echo ===================================================================== -eval $base_count; - prepare stmt from 'select * from mysql.general_log where argument=\'IMPOSSIBLE QUERY STRING\''; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; --echo ===================================================================== --echo Testing 21: Special tables (system tables) @@ -996,25 +985,23 @@ eval $reprepared; drop procedure if exists proc_21; --enable_warnings -eval $base_count; - prepare stmt from 'select type, db, name from mysql.proc where name=\'proc_21\''; create procedure proc_21() select "hi there"; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop procedure proc_21; create procedure proc_21() select "hi there, again"; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop procedure proc_21; @@ -1027,8 +1014,6 @@ drop table if exists t22_b; drop view if exists t22; --enable_warnings -eval $base_count; - create table t22_b(a int); create algorithm=temptable view t22 as select a*a as a2 from t22_b; @@ -1041,15 +1026,15 @@ prepare stmt from 'select * from t22'; insert into t22_b values (1), (2), (3); execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; insert into t22_b values (4), (5), (6); execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t22_b; drop view t22; @@ -1063,8 +1048,6 @@ drop table if exists t23_a; drop table if exists t23_b; --enable_warnings -eval $base_count; - create table t23_a(a int); create table t23_b(b int); @@ -1075,16 +1058,16 @@ prepare stmt from 'select * from t23_a join t23_b'; insert into t23_a values (1), (2), (3); insert into t23_b values (10), (20), (30); execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; insert into t23_a values (4); insert into t23_b values (40); execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t23_a; drop table t23_b; @@ -1099,28 +1082,26 @@ drop table t23_b; drop table if exists t24_alter; --enable_warnings -eval $base_count; - create table t24_alter(a int); prepare stmt from 'alter table t24_alter add column b int'; execute stmt; -eval $reprepared; +eval $check; drop table t24_alter; create table t24_alter(a1 int, a2 int); # t24_alter has changed, and it's not a problem execute stmt; -eval $reprepared; +eval $check; alter table t24_alter drop column b; execute stmt; -eval $reprepared; +eval $check; alter table t24_alter drop column b; execute stmt; -eval $reprepared; +eval $check; drop table t24_alter; @@ -1135,7 +1116,7 @@ insert into t24_repair values (1), (2), (3); prepare stmt from 'repair table t24_repair'; execute stmt; -eval $reprepared; +eval $check; drop table t24_repair; create table t24_repair(a1 int, a2 int); @@ -1143,15 +1124,15 @@ insert into t24_repair values (1, 10), (2, 20), (3, 30); # t24_repair has changed, and it's not a problem execute stmt; -eval $reprepared; +eval $check; alter table t24_repair add column b varchar(50) default NULL; execute stmt; -eval $reprepared; +eval $check; alter table t24_repair drop column b; execute stmt; -eval $reprepared; +eval $check; drop table t24_repair; @@ -1166,7 +1147,7 @@ insert into t24_analyze values (1), (2), (3); prepare stmt from 'analyze table t24_analyze'; execute stmt; -eval $reprepared; +eval $check; drop table t24_analyze; create table t24_analyze(a1 int, a2 int); @@ -1174,15 +1155,15 @@ insert into t24_analyze values (1, 10), (2, 20), (3, 30); # t24_analyze has changed, and it's not a problem execute stmt; -eval $reprepared; +eval $check; alter table t24_analyze add column b varchar(50) default NULL; execute stmt; -eval $reprepared; +eval $check; alter table t24_analyze drop column b; execute stmt; -eval $reprepared; +eval $check; drop table t24_analyze; @@ -1197,7 +1178,7 @@ insert into t24_optimize values (1), (2), (3); prepare stmt from 'optimize table t24_optimize'; execute stmt; -eval $reprepared; +eval $check; drop table t24_optimize; create table t24_optimize(a1 int, a2 int); @@ -1205,15 +1186,15 @@ insert into t24_optimize values (1, 10), (2, 20), (3, 30); # t24_optimize has changed, and it's not a problem execute stmt; -eval $reprepared; +eval $check; alter table t24_optimize add column b varchar(50) default NULL; execute stmt; -eval $reprepared; +eval $check; alter table t24_optimize drop column b; execute stmt; -eval $reprepared; +eval $check; drop table t24_optimize; @@ -1226,35 +1207,35 @@ drop procedure if exists changing_proc; prepare stmt from 'show create procedure changing_proc'; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; create procedure changing_proc() begin end; # changing_proc has changed, and it's not a problem execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop procedure changing_proc; create procedure changing_proc(x int, y int) begin end; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop procedure changing_proc; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; # SQLCOM_SHOW_CREATE_FUNC: @@ -1265,35 +1246,35 @@ drop function if exists changing_func; prepare stmt from 'show create function changing_func'; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; create function changing_func() returns int return 0; # changing_proc has changed, and it's not a problem execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop function changing_func; create function changing_func(x int, y int) returns int return x+y; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop function changing_func; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; --error ER_SP_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; # SQLCOM_SHOW_CREATE_TRIGGER: @@ -1306,10 +1287,10 @@ create table t24_trigger(a int); prepare stmt from 'show create trigger t24_bi;'; --error ER_TRG_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; --error ER_TRG_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; delimiter $$; create trigger t24_bi before insert on t24_trigger for each row @@ -1321,9 +1302,9 @@ delimiter ;$$ # t24_bi has changed, and it's not a problem execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop trigger t24_bi; delimiter $$; @@ -1335,19 +1316,20 @@ $$ delimiter ;$$ # t24_bi has changed, and it's not a problem +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop trigger t24_bi; --error ER_TRG_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; --error ER_TRG_DOES_NOT_EXIST execute stmt; -eval $reprepared; +eval $check; drop table t24_trigger; @@ -1361,23 +1343,21 @@ drop table t24_trigger; drop table if exists t25_num_col; --enable_warnings -eval $base_count; - create table t25_num_col(a int); -prepare stmt from 'select * from t25_num_col'; +prepare stmt from 'select a from t25_num_col'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; alter table t25_num_col add column b varchar(50) default NULL; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t25_num_col; @@ -1391,17 +1371,20 @@ create table t25_col_name(a int); prepare stmt from 'select * from t25_col_name'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; alter table t25_col_name change a b int; -# REPREPARED +1 +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; drop table t25_col_name; @@ -1415,17 +1398,20 @@ create table t25_col_type(a int); prepare stmt from 'select * from t25_col_type'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; alter table t25_col_type change a a varchar(10); -# REPREPARED +1 +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; drop table t25_col_type; @@ -1439,17 +1425,20 @@ create table t25_col_type_length(a varchar(10)); prepare stmt from 'select * from t25_col_type_length'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; alter table t25_col_type_length change a a varchar(20); -# REPREPARED +1 +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; drop table t25_col_type_length; @@ -1463,17 +1452,20 @@ create table t25_col_null(a varchar(10)); prepare stmt from 'select * from t25_col_null'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; alter table t25_col_null change a a varchar(10) NOT NULL; -# REPREPARED +1 +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; drop table t25_col_null; @@ -1488,22 +1480,23 @@ create table t25_col_default(a int, b int DEFAULT 10); prepare stmt from 'insert into t25_col_default(a) values (?)'; set @val=1; execute stmt using @val; -eval $reprepared; +eval $check; set @val=2; execute stmt using @val; -eval $reprepared; +eval $check; alter table t25_col_default change b b int DEFAULT 20; set @val=3; # Must insert the correct default value for b +set @expected = @expected + 1; execute stmt using @val; -eval $reprepared; +eval $check; set @val=4; # Must insert the correct default value for b execute stmt using @val; -eval $reprepared; +eval $check; select * from t25_col_default; @@ -1519,17 +1512,17 @@ create table t25_index(a varchar(10)); prepare stmt from 'select * from t25_index'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; create index i1 on t25_index(a); -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t25_index; @@ -1546,20 +1539,20 @@ show create table t25_index_unique; prepare stmt from 'select * from t25_index_unique'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; alter table t25_index_unique drop index i1; create unique index i1 on t25_index_unique(a, b); show create table t25_index_unique; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t25_index_unique; @@ -1579,8 +1572,6 @@ drop function if exists func_12093_unrelated; drop procedure if exists proc_12093; --enable_warnings -eval $base_count; - connect (con1,localhost,root,,); connection default; @@ -1609,9 +1600,9 @@ prepare stmt_sf from 'select func_12093();'; prepare stmt_sp from 'call proc_12093(func_12093())'; execute stmt_sf; -eval $reprepared; +eval $check; execute stmt_sp; -eval $reprepared; +eval $check; connection con1; @@ -1622,17 +1613,17 @@ connection default; # previously, failed with --error 1305 execute stmt_sf; -eval $reprepared; +eval $check; # previously, failed with --error 1305 execute stmt_sp; -eval $reprepared; +eval $check; # previously, failed with --error 1305 execute stmt_sf; -eval $reprepared; +eval $check; # previously, failed with --error 1305 execute stmt_sp; -eval $reprepared; +eval $check; deallocate prepare stmt_sf; deallocate prepare stmt_sp; @@ -1652,26 +1643,25 @@ drop procedure proc_12093; drop function if exists func_21294; --enable_warnings -eval $base_count; - create function func_21294() returns int return 10; prepare stmt from "select func_21294()"; execute stmt; -eval $reprepared; +eval $check; drop function func_21294; create function func_21294() returns int return 10; # might pass or fail, implementation dependent execute stmt; -eval $reprepared; +eval $check; drop function func_21294; create function func_21294() returns int return 20; +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; deallocate prepare stmt; drop function func_21294; @@ -1687,8 +1677,6 @@ drop table if exists t_27420_101; drop view if exists v_27420; --enable_warnings -eval $base_count; - connect (con1,localhost,root,,); connection default; @@ -1706,7 +1694,7 @@ create view v_27420 as select t_27420_100.a X, t_27420_101.a Y prepare stmt from 'select * from v_27420'; execute stmt; -eval $reprepared; +eval $check; connection con1; @@ -1715,9 +1703,9 @@ create table v_27420(X int, Y int); connection default; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; connection con1; @@ -1727,9 +1715,10 @@ create table v_27420 (a int, b int, filler char(200)); connection default; -# REPREPARED +1 +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; disconnect con1; @@ -1748,8 +1737,6 @@ drop table if exists t_27430_1; drop table if exists t_27430_2; --enable_warnings -eval $base_count; - create table t_27430_1 (a int not null, oref int not null, key(a)); insert into t_27430_1 values (1, 1), @@ -1769,9 +1756,9 @@ prepare stmt from 'select oref, a, a in (select a from t_27430_1 where oref=t_27430_2.oref) Z from t_27430_2'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table t_27430_1, t_27430_2; @@ -1790,11 +1777,14 @@ insert into t_27430_2 values (NULL, 3), (NULL, 4); -# REPREPARED +1 +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; +set @expected = @expected + 1; +--error ER_PS_REBIND execute stmt; -eval $reprepared; +eval $check; deallocate prepare stmt; drop table t_27430_1; @@ -1811,8 +1801,6 @@ drop view if exists v_27690_1; drop table if exists v_27690_2; --enable_warnings -eval $base_count; - create table t_27690_1 (a int, b int); insert into t_27690_1 values (1,1),(2,2); @@ -1822,27 +1810,27 @@ create table v_27690_2 as select * from t_27690_1; prepare stmt from 'select * from v_27690_1, v_27690_2'; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; drop table v_27690_1; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; --error ER_NO_SUCH_TABLE execute stmt; -eval $reprepared; +eval $check; create view v_27690_1 as select A.a, A.b from t_27690_1 A, t_27690_1 B; -# REPREPARED +1 +set @expected = @expected + 1; execute stmt; -eval $reprepared; +eval $check; execute stmt; -eval $reprepared; +eval $check; deallocate prepare stmt; drop table t_27690_1; diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 34e1941c9d7..613e9acc4c4 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -1115,5 +1115,24 @@ DROP EVENT ev1; SHOW TABLE TYPES; --enable_result_log +# +# Bug #32710: SHOW INNODB STATUS requires SUPER +# + + +CREATE USER test_u@localhost; +GRANT PROCESS ON *.* TO test_u@localhost; + +connect (conn1, localhost, test_u,,); + +--disable_result_log +SHOW ENGINE MYISAM MUTEX; +SHOW ENGINE MYISAM STATUS; +--enable_result_log + +disconnect conn1; +connection default; +DROP USER test_u@localhost; + --echo End of 5.1 tests diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 286722df65c..23bce3805af 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -2368,6 +2368,24 @@ end| delimiter ;| +# +# Bug#21801: SQL exception handlers and warnings +# + +--disable_warnings +drop procedure if exists p1; +--enable_warnings +delimiter |; +create procedure p1() +begin + create table t1 (a int) type=MyISAM; + drop table t1; +end| +delimiter ;| +call p1(); +call p1(); +drop procedure p1; + # # BUG#NNNN: New bug synopsis # diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 6dc2f906d45..bb9aae6dee6 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -8135,6 +8135,29 @@ DROP FUNCTION f1; ########################################################################### +# +# Bug#32633 Can not create any routine if SQL_MODE=no_engine_substitution +# +# Ensure that when new SQL modes are introduced, they are also added to +# the mysql.proc table. +# + +--disable_warnings +drop procedure if exists p; +--enable_warnings +set @old_mode= @@sql_mode; +set @@sql_mode= pow(2,32)-1; +select @@sql_mode into @full_mode; +create procedure p() begin end; +call p(); +select @@sql_mode; +set @@sql_mode= @old_mode; +# Rename SQL modes that differ in name between the server and the table definition. +select replace(@full_mode, '?', 'NOT_USED') into @full_mode; +select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode; +select name from mysql.proc where name = 'p' and sql_mode = @full_mode; +drop procedure p; + --echo # ------------------------------------------------------------------ --echo # -- End of 5.1 tests --echo # ------------------------------------------------------------------ diff --git a/mysql-test/t/system_mysql_db_fix50117.test b/mysql-test/t/system_mysql_db_fix50117.test index 5f259ac6133..ea379757f26 100644 --- a/mysql-test/t/system_mysql_db_fix50117.test +++ b/mysql-test/t/system_mysql_db_fix50117.test @@ -78,7 +78,7 @@ CREATE TABLE IF NOT EXISTS proc ( db char(64) collate utf8_bin DEFAULT '' NOT NU CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges'; -CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events'; +CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events'; CREATE TABLE IF NOT EXISTS ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM; diff --git a/mysql-test/t/upgrade.test b/mysql-test/t/upgrade.test index 05f430b087b..ce40ec8ed77 100644 --- a/mysql-test/t/upgrade.test +++ b/mysql-test/t/upgrade.test @@ -1,10 +1,5 @@ -- source include/not_embedded.inc -# Temporary disabled on windows, -# because of --exec mkdir -# TODO: implement Bug#31004 and remove this limitation ---source include/not_windows.inc - --disable_warnings drop database if exists `mysqltest1`; drop database if exists `mysqltest-1`; @@ -75,7 +70,7 @@ create table tabc.t1 (a int); FLUSH TABLES; # Manually make a 5.0 database from the template ---exec mkdir $MYSQLTEST_VARDIR/master-data/a-b-c +--mkdir $MYSQLTEST_VARDIR/master-data/a-b-c --copy_file $MYSQLTEST_VARDIR/master-data/tabc/db.opt $MYSQLTEST_VARDIR/master-data/a-b-c/db.opt --copy_file $MYSQLTEST_VARDIR/master-data/tabc/t1.frm $MYSQLTEST_VARDIR/master-data/a-b-c/t1.frm --copy_file $MYSQLTEST_VARDIR/master-data/tabc/t1.MYD $MYSQLTEST_VARDIR/master-data/a-b-c/t1.MYD diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 7f7be4835a5..afe8f289089 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -405,6 +405,8 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, wait->last= &data->next; } + statistic_increment(locks_waited, &THR_LOCK_lock); + /* Set up control struct to allow others to abort locks */ thread_var->current_mutex= &data->lock->mutex; thread_var->current_cond= cond; @@ -469,7 +471,6 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, else { result= THR_LOCK_SUCCESS; - statistic_increment(locks_waited, &THR_LOCK_lock); if (data->lock->get_status) (*data->lock->get_status)(data->status_param, 0); check_locks(data->lock,"got wait_for_lock",0); diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index 7ca35ae0752..fdab9601129 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -60,7 +60,7 @@ CREATE TABLE IF NOT EXISTS time_zone_transition_type ( Time_zone_id int unsign CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=MyISAM CHARACTER SET utf8 comment='Leap seconds information for time zones'; -CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures'; +CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures'; CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges'; @@ -80,7 +80,7 @@ PREPARE stmt FROM @str; EXECUTE stmt; DROP PREPARE stmt; -CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator int(10) NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events'; +CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator int(10) NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events'; CREATE TABLE IF NOT EXISTS ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM; diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index a43964bf09a..e2bdd668c0f 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -375,7 +375,9 @@ ALTER TABLE proc MODIFY name char(64) DEFAULT '' NOT NULL, 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', - 'HIGH_NOT_PRECEDENCE' + 'HIGH_NOT_PRECEDENCE', + 'NO_ENGINE_SUBSTITUTION', + 'PAD_CHAR_TO_FULL_LENGTH' ) DEFAULT '' NOT NULL, DEFAULT CHARACTER SET utf8; @@ -461,7 +463,9 @@ ALTER TABLE event ADD sql_mode 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', - 'HIGH_NOT_PRECEDENCE' + 'HIGH_NOT_PRECEDENCE', + 'NO_ENGINE_SUBSTITUTION', + 'PAD_CHAR_TO_FULL_LENGTH' ) DEFAULT '' NOT NULL AFTER on_completion; ALTER TABLE event MODIFY name char(64) CHARACTER SET utf8 NOT NULL default ''; ALTER TABLE event ADD COLUMN originator INT(10) NOT NULL AFTER comment; diff --git a/sql-common/my_user.c b/sql-common/my_user.c index 16a544387ee..d6f2818ad77 100644 --- a/sql-common/my_user.c +++ b/sql-common/my_user.c @@ -15,7 +15,7 @@ #include #include - +#include /* Parse user value to user name and host name parts. @@ -47,6 +47,12 @@ void parse_user(const char *user_id_str, size_t user_id_len, *user_name_len= p - user_id_str; *host_name_len= user_id_len - *user_name_len - 1; + if (*user_name_len > USERNAME_LENGTH) + *user_name_len= USERNAME_LENGTH; + + if (*host_name_len > HOSTNAME_LENGTH) + *host_name_len= HOSTNAME_LENGTH; + memcpy(user_name_str, user_id_str, *user_name_len); memcpy(host_name_str, p + 1, *host_name_len); } diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index 9a33b33d8c9..401f76f5d26 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -111,7 +111,7 @@ const TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] = "'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES'," "'STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES'," "'ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER'," - "'HIGH_NOT_PRECEDENCE')") }, + "'HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')") }, {NULL, 0} }, { @@ -172,11 +172,13 @@ mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et, sp_head *sp, + ulong sql_mode, my_bool is_update) { CHARSET_INFO *scs= system_charset_info; enum enum_events_table_field f_num; Field **fields= table->field; + int rs= FALSE; DBUG_ENTER("mysql_event_fill_row"); @@ -205,12 +207,9 @@ mysql_event_fill_row(THD *thd, goto err_truncate; /* both ON_COMPLETION and STATUS are NOT NULL thus not calling set_notnull()*/ - fields[ET_FIELD_ON_COMPLETION]->store((longlong)et->on_completion, TRUE); - - fields[ET_FIELD_STATUS]->store((longlong)et->status, TRUE); - - fields[ET_FIELD_ORIGINATOR]->store((longlong)et->originator, TRUE); - + rs|= fields[ET_FIELD_ON_COMPLETION]->store((longlong)et->on_completion, TRUE); + rs|= fields[ET_FIELD_STATUS]->store((longlong)et->status, TRUE); + rs|= fields[ET_FIELD_ORIGINATOR]->store((longlong)et->originator, TRUE); /* Change the SQL_MODE only if body was present in an ALTER EVENT and of course @@ -220,7 +219,7 @@ mysql_event_fill_row(THD *thd, { DBUG_ASSERT(sp->m_body.str); - fields[ET_FIELD_SQL_MODE]->store((longlong)thd->variables.sql_mode, TRUE); + rs|= fields[ET_FIELD_SQL_MODE]->store((longlong)sql_mode, TRUE); if (fields[f_num= ET_FIELD_BODY]->store(sp->m_body.str, sp->m_body.length, @@ -236,16 +235,16 @@ mysql_event_fill_row(THD *thd, if (!is_update || !et->starts_null) { fields[ET_FIELD_TIME_ZONE]->set_notnull(); - fields[ET_FIELD_TIME_ZONE]->store(tz_name->ptr(), tz_name->length(), - tz_name->charset()); + rs|= fields[ET_FIELD_TIME_ZONE]->store(tz_name->ptr(), tz_name->length(), + tz_name->charset()); } fields[ET_FIELD_INTERVAL_EXPR]->set_notnull(); - fields[ET_FIELD_INTERVAL_EXPR]->store((longlong)et->expression, TRUE); + rs|= fields[ET_FIELD_INTERVAL_EXPR]->store((longlong)et->expression, TRUE); fields[ET_FIELD_TRANSIENT_INTERVAL]->set_notnull(); - fields[ET_FIELD_TRANSIENT_INTERVAL]-> + rs|= fields[ET_FIELD_TRANSIENT_INTERVAL]-> store(interval_type_to_name[et->interval].str, interval_type_to_name[et->interval].length, scs); @@ -274,8 +273,8 @@ mysql_event_fill_row(THD *thd, { const String *tz_name= thd->variables.time_zone->get_name(); fields[ET_FIELD_TIME_ZONE]->set_notnull(); - fields[ET_FIELD_TIME_ZONE]->store(tz_name->ptr(), tz_name->length(), - tz_name->charset()); + rs|= fields[ET_FIELD_TIME_ZONE]->store(tz_name->ptr(), tz_name->length(), + tz_name->charset()); fields[ET_FIELD_INTERVAL_EXPR]->set_null(); fields[ET_FIELD_TRANSIENT_INTERVAL]->set_null(); @@ -308,13 +307,13 @@ mysql_event_fill_row(THD *thd, } fields[ET_FIELD_CHARACTER_SET_CLIENT]->set_notnull(); - fields[ET_FIELD_CHARACTER_SET_CLIENT]->store( + rs|= fields[ET_FIELD_CHARACTER_SET_CLIENT]->store( thd->variables.character_set_client->csname, strlen(thd->variables.character_set_client->csname), system_charset_info); fields[ET_FIELD_COLLATION_CONNECTION]->set_notnull(); - fields[ET_FIELD_COLLATION_CONNECTION]->store( + rs|= fields[ET_FIELD_COLLATION_CONNECTION]->store( thd->variables.collation_connection->name, strlen(thd->variables.collation_connection->name), system_charset_info); @@ -323,15 +322,23 @@ mysql_event_fill_row(THD *thd, CHARSET_INFO *db_cl= get_default_db_collation(thd, et->dbname.str); fields[ET_FIELD_DB_COLLATION]->set_notnull(); - fields[ET_FIELD_DB_COLLATION]->store( - db_cl->name, strlen(db_cl->name), system_charset_info); + rs|= fields[ET_FIELD_DB_COLLATION]->store(db_cl->name, + strlen(db_cl->name), + system_charset_info); } if (et->body_changed) { fields[ET_FIELD_BODY_UTF8]->set_notnull(); - fields[ET_FIELD_BODY_UTF8]->store( - sp->m_body_utf8.str, sp->m_body_utf8.length, system_charset_info); + rs|= fields[ET_FIELD_BODY_UTF8]->store(sp->m_body_utf8.str, + sp->m_body_utf8.length, + system_charset_info); + } + + if (rs) + { + my_error(ER_EVENT_STORE_FAILED, MYF(0), fields[f_num]->field_name, rs); + DBUG_RETURN(TRUE); } DBUG_RETURN(FALSE); @@ -585,12 +592,16 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, int ret= 1; TABLE *table= NULL; sp_head *sp= thd->lex->sphead; + ulong saved_mode= thd->variables.sql_mode; DBUG_ENTER("Event_db_repository::create_event"); DBUG_PRINT("info", ("open mysql.event for update")); DBUG_ASSERT(sp); + /* Reset sql_mode during data dictionary operations. */ + thd->variables.sql_mode= 0; + if (open_event_table(thd, TL_WRITE, &table)) goto end; @@ -646,7 +657,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, mysql_event_fill_row() calls my_error() in case of error so no need to handle it here */ - if (mysql_event_fill_row(thd, table, parse_data, sp, FALSE)) + if (mysql_event_fill_row(thd, table, parse_data, sp, saved_mode, FALSE)) goto end; table->field[ET_FIELD_STATUS]->store((longlong)parse_data->status, TRUE); @@ -661,6 +672,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, end: if (table) close_thread_tables(thd); + thd->variables.sql_mode= saved_mode; DBUG_RETURN(test(ret)); } @@ -691,6 +703,7 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data, CHARSET_INFO *scs= system_charset_info; TABLE *table= NULL; sp_head *sp= thd->lex->sphead; + ulong saved_mode= thd->variables.sql_mode; int ret= 1; DBUG_ENTER("Event_db_repository::update_event"); @@ -698,6 +711,9 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data, /* None or both must be set */ DBUG_ASSERT(new_dbname && new_name || new_dbname == new_name); + /* Reset sql_mode during data dictionary operations. */ + thd->variables.sql_mode= 0; + if (open_event_table(thd, TL_WRITE, &table)) goto end; @@ -736,7 +752,7 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data, mysql_event_fill_row() calls my_error() in case of error so no need to handle it here */ - if (mysql_event_fill_row(thd, table, parse_data, sp, TRUE)) + if (mysql_event_fill_row(thd, table, parse_data, sp, saved_mode, TRUE)) goto end; if (new_dbname) @@ -755,6 +771,7 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data, end: if (table) close_thread_tables(thd); + thd->variables.sql_mode= saved_mode; DBUG_RETURN(test(ret)); } @@ -950,13 +967,17 @@ bool Event_db_repository::load_named_event(THD *thd, LEX_STRING dbname, LEX_STRING name, Event_basic *etn) { - TABLE *table= NULL; bool ret; + TABLE *table= NULL; + ulong saved_mode= thd->variables.sql_mode; DBUG_ENTER("Event_db_repository::load_named_event"); DBUG_PRINT("enter",("thd: 0x%lx name: %*s", (long) thd, (int) name.length, name.str)); + /* Reset sql_mode during data dictionary operations. */ + thd->variables.sql_mode= 0; + if (!(ret= open_event_table(thd, TL_READ, &table))) { if ((ret= find_named_event(dbname, name, table))) @@ -967,7 +988,7 @@ Event_db_repository::load_named_event(THD *thd, LEX_STRING dbname, close_thread_tables(thd); } - + thd->variables.sql_mode= saved_mode; DBUG_RETURN(ret); } diff --git a/sql/item.cc b/sql/item.cc index c546badd8e7..ab9243fcaf5 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2628,6 +2628,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry) if (entry && entry->value) { item_result_type= entry->type; + unsigned_flag= entry->unsigned_flag; if (strict_type && required_result_type != item_result_type) DBUG_RETURN(1); switch (item_result_type) { @@ -2925,7 +2926,7 @@ const String *Item_param::query_val_str(String* str) const { switch (state) { case INT_VALUE: - str->set(value.integer, &my_charset_bin); + str->set_int(value.integer, unsigned_flag, &my_charset_bin); break; case REAL_VALUE: str->set_real(value.real, NOT_FIXED_DEC, &my_charset_bin); diff --git a/sql/log.cc b/sql/log.cc index fce1eb076db..9b5b2ae5a6c 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -73,23 +73,28 @@ static int binlog_prepare(handlerton *hton, THD *thd, bool all); */ class Silence_log_table_errors : public Internal_error_handler { + char m_message[MYSQL_ERRMSG_SIZE]; public: Silence_log_table_errors() - {} + { + m_message[0]= '\0'; + } virtual ~Silence_log_table_errors() {} virtual bool handle_error(uint sql_errno, const char *message, MYSQL_ERROR::enum_warning_level level, THD *thd); + const char *message() const { return m_message; } }; bool Silence_log_table_errors::handle_error(uint /* sql_errno */, - const char * /* message */, + const char *message_arg, MYSQL_ERROR::enum_warning_level /* level */, THD * /* thd */) { + strmake(m_message, message_arg, sizeof(m_message)-1); return TRUE; } @@ -436,8 +441,9 @@ bool Log_to_csv_event_handler:: result= FALSE; err: - if (result) - sql_print_error("Failed to write to mysql.general_log"); + if (result && !thd->killed) + sql_print_error("Failed to write to mysql.general_log: %s", + error_handler.message()); if (need_rnd_end) { @@ -495,11 +501,13 @@ bool Log_to_csv_event_handler:: bool result= TRUE; bool need_close= FALSE; bool need_rnd_end= FALSE; + Silence_log_table_errors error_handler; Open_tables_state open_tables_backup; CHARSET_INFO *client_cs= thd->variables.character_set_client; bool save_time_zone_used; DBUG_ENTER("Log_to_csv_event_handler::log_slow"); + thd->push_internal_handler(& error_handler); /* CSV uses TIME_to_timestamp() internally if table needs to be repaired which will set thd->time_zone_used @@ -629,8 +637,11 @@ bool Log_to_csv_event_handler:: result= FALSE; err: - if (result) - sql_print_error("Failed to write to mysql.slow_log"); + thd->pop_internal_handler(); + + if (result && !thd->killed) + sql_print_error("Failed to write to mysql.slow_log: %s", + error_handler.message()); if (need_rnd_end) { diff --git a/sql/log_event.cc b/sql/log_event.cc index 85a629c2389..430d7921849 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -99,27 +99,51 @@ static const char *HA_ERR(int i) case HA_ERR_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME"; case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE"; case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT"; + case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY"; } return 0; } /** - macro to call from different branches of Rows_log_event::do_apply_event + Error reporting facility for Rows_log_event::do_apply_event + + @param level error, warning or info + @param ha_error HA_ERR_ code + @param rli pointer to the active Relay_log_info instance + @param thd pointer to the slave thread's thd + @param table pointer to the event's table object + @param type the type of the event + @param log_name the master binlog file name + @param pos the master binlog file pos (the next after the event) + */ static void inline slave_rows_error_report(enum loglevel level, int ha_error, Relay_log_info const *rli, THD *thd, TABLE *table, const char * type, const char *log_name, ulong pos) { - const char *handler_error= HA_ERR(ha_error); + const char *handler_error= HA_ERR(ha_error); + char buff[MAX_SLAVE_ERRMSG], *slider; + const char *buff_end= buff + sizeof(buff); + uint len; + List_iterator_fast it(thd->warn_list); + MYSQL_ERROR *err; + buff[0]= 0; + + for (err= it++, slider= buff; err && slider < buff_end - 1; + slider += len, err= it++) + { + len= my_snprintf(slider, buff_end - slider, + " %s, Error_code: %d;", err->msg, err->code); + } + rli->report(level, thd->net.client_last_errno, "Could not execute %s event on table %s.%s;" - "%s%s handler error %s; " + "%s handler error %s; " "the event's master log %s, end_log_pos %lu", type, table->s->db.str, table->s->table_name.str, - thd->net.client_last_error[0] != 0 ? thd->net.client_last_error : "", - thd->net.client_last_error[0] != 0 ? ";" : "", + buff, handler_error == NULL? "" : handler_error, log_name, pos); } @@ -212,9 +236,9 @@ uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation */ #ifdef MYSQL_CLIENT -static void pretty_print_str(IO_CACHE* cache, char* str, int len) +static void pretty_print_str(IO_CACHE* cache, const char* str, int len) { - char* end = str + len; + const char* end = str + len; my_b_printf(cache, "\'"); while (str < end) { @@ -277,9 +301,9 @@ inline int ignored_error_code(int err_code) */ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -static char *pretty_print_str(char *packet, char *str, int len) +static char *pretty_print_str(char *packet, const char *str, int len) { - char *end= str + len; + const char *end= str + len; char *pos= packet; *pos++= '\''; while (str < end) @@ -385,7 +409,7 @@ static void cleanup_load_tmpdir() write_str() */ -static bool write_str(IO_CACHE *file, char *str, uint length) +static bool write_str(IO_CACHE *file, const char *str, uint length) { uchar tmp[1]; tmp[0]= (uchar) length; @@ -2957,18 +2981,63 @@ Format_description_log_event(const char* buf, If post_header_len is null, it means malloc failed, and is_valid will fail, so there is no need to do anything. - The trees which have wrong event id's are: - mysql-5.1-wl2325-5.0-drop6p13-alpha, mysql-5.1-wl2325-5.0-drop6, - mysql-5.1-wl2325-5.0, mysql-5.1-wl2325-no-dd (`grep -C2 - BEGIN_LOAD_QUERY_EVENT /home/bk/ * /sql/log_event.h`). The - corresponding version (`grep mysql, configure.in` in those trees) - strings are 5.2.2-a_drop6p13-alpha, 5.2.2-a_drop6p13c, - 5.1.5-a_drop5p20, 5.1.2-a_drop5p5. + The trees in which events have wrong id's are: + + mysql-5.1-wl1012.old mysql-5.1-wl2325-5.0-drop6p13-alpha + mysql-5.1-wl2325-5.0-drop6 mysql-5.1-wl2325-5.0 + mysql-5.1-wl2325-no-dd + + (this was found by grepping for two lines in sequence where the + first matches "FORMAT_DESCRIPTION_EVENT," and the second matches + "TABLE_MAP_EVENT," in log_event.h in all trees) + + In these trees, the following server_versions existed since + TABLE_MAP_EVENT was introduced: + + 5.1.1-a_drop5p3 5.1.1-a_drop5p4 5.1.1-alpha + 5.1.2-a_drop5p10 5.1.2-a_drop5p11 5.1.2-a_drop5p12 + 5.1.2-a_drop5p13 5.1.2-a_drop5p14 5.1.2-a_drop5p15 + 5.1.2-a_drop5p16 5.1.2-a_drop5p16b 5.1.2-a_drop5p16c + 5.1.2-a_drop5p17 5.1.2-a_drop5p4 5.1.2-a_drop5p5 + 5.1.2-a_drop5p6 5.1.2-a_drop5p7 5.1.2-a_drop5p8 + 5.1.2-a_drop5p9 5.1.3-a_drop5p17 5.1.3-a_drop5p17b + 5.1.3-a_drop5p17c 5.1.4-a_drop5p18 5.1.4-a_drop5p19 + 5.1.4-a_drop5p20 5.1.4-a_drop6p0 5.1.4-a_drop6p1 + 5.1.4-a_drop6p2 5.1.5-a_drop5p20 5.2.0-a_drop6p3 + 5.2.0-a_drop6p4 5.2.0-a_drop6p5 5.2.0-a_drop6p6 + 5.2.1-a_drop6p10 5.2.1-a_drop6p11 5.2.1-a_drop6p12 + 5.2.1-a_drop6p6 5.2.1-a_drop6p7 5.2.1-a_drop6p8 + 5.2.2-a_drop6p13 5.2.2-a_drop6p13-alpha 5.2.2-a_drop6p13b + 5.2.2-a_drop6p13c + + (this was found by grepping for "mysql," in all historical + versions of configure.in in the trees listed above). + + There are 5.1.1-alpha versions that use the new event id's, so we + do not test that version string. So replication from 5.1.1-alpha + with the other event id's to a new version does not work. + Moreover, we can safely ignore the part after drop[56]. This + allows us to simplify the big list above to the following regexes: + + 5\.1\.[1-5]-a_drop5.* + 5\.1\.4-a_drop6.* + 5\.2\.[0-2]-a_drop6.* + + This is what we test for in the 'if' below. */ if (post_header_len && - (strncmp(server_version, "5.1.2-a_drop5", 13) == 0 || - strncmp(server_version, "5.1.5-a_drop5", 13) == 0 || - strncmp(server_version, "5.2.2-a_drop6", 13) == 0)) + server_version[0] == '5' && server_version[1] == '.' && + server_version[3] == '.' && + strncmp(server_version + 5, "-a_drop", 7) == 0 && + ((server_version[2] == '1' && + server_version[4] >= '1' && server_version[4] <= '5' && + server_version[12] == '5') || + (server_version[2] == '1' && + server_version[4] == '4' && + server_version[12] == '6') || + (server_version[2] == '2' && + server_version[4] >= '0' && server_version[4] <= '2' && + server_version[12] == '6'))) { if (number_of_event_types != 22) { @@ -6026,7 +6095,8 @@ bool sql_ex_info::write_data(IO_CACHE* file) sql_ex_info::init() */ -char *sql_ex_info::init(char *buf, char *buf_end, bool use_new_format) +const char *sql_ex_info::init(const char *buf, const char *buf_end, + bool use_new_format) { cached_new_format = use_new_format; if (use_new_format) @@ -6039,12 +6109,11 @@ char *sql_ex_info::init(char *buf, char *buf_end, bool use_new_format) the case when we have old format because we will be reusing net buffer to read the actual file before we write out the Create_file event. */ - const char *ptr= buf; - if (read_str(&ptr, buf_end, (const char **) &field_term, &field_term_len) || - read_str(&ptr, buf_end, (const char **) &enclosed, &enclosed_len) || - read_str(&ptr, buf_end, (const char **) &line_term, &line_term_len) || - read_str(&ptr, buf_end, (const char **) &line_start, &line_start_len) || - read_str(&ptr, buf_end, (const char **) &escaped, &escaped_len)) + if (read_str(&buf, buf_end, &field_term, &field_term_len) || + read_str(&buf, buf_end, &enclosed, &enclosed_len) || + read_str(&buf, buf_end, &line_term, &line_term_len) || + read_str(&buf, buf_end, &line_start, &line_start_len) || + read_str(&buf, buf_end, &escaped, &escaped_len)) return 0; opt_flags = *buf++; } @@ -7646,7 +7715,7 @@ Rows_log_event::write_row(const Relay_log_info *const rli, /* fill table->record[0] with default values */ - if ((error= prepare_record(rli, table, m_width, + if ((error= prepare_record(table, m_width, TRUE /* check if columns have def. values */))) DBUG_RETURN(error); @@ -7964,13 +8033,17 @@ int Rows_log_event::find_row(const Relay_log_info *rli) DBUG_ASSERT(m_table && m_table->in_use != NULL); TABLE *table= m_table; - int error; + int error= 0; - /* unpack row - missing fields get default values */ - - // TODO: shall we check and report errors here? - prepare_record(NULL,table,m_width,FALSE /* don't check errors */); - error= unpack_current_row(rli); + /* + rpl_row_tabledefs.test specifies that + if the extra field on the slave does not have a default value + and this is okay with Delete or Update events. + Todo: fix wl3228 hld that requires defauls for all types of events + */ + + prepare_record(table, m_width, FALSE); + error= unpack_current_row(rli); #ifndef DBUG_OFF DBUG_PRINT("info",("looking for the following record")); diff --git a/sql/log_event.h b/sql/log_event.h index efb8675780e..4e151d6cde9 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -152,11 +152,11 @@ struct old_sql_ex struct sql_ex_info { sql_ex_info() {} /* Remove gcc warning */ - char* field_term; - char* enclosed; - char* line_term; - char* line_start; - char* escaped; + const char* field_term; + const char* enclosed; + const char* line_term; + const char* line_start; + const char* escaped; int cached_new_format; uint8 field_term_len,enclosed_len,line_term_len,line_start_len, escaped_len; char opt_flags; @@ -171,7 +171,7 @@ struct sql_ex_info line_start_len + escaped_len + 6 : 7); } bool write_data(IO_CACHE* file); - char* init(char* buf,char* buf_end,bool use_new_format); + const char* init(const char* buf, const char* buf_end, bool use_new_format); bool new_format() { return ((cached_new_format != -1) ? cached_new_format : @@ -667,34 +667,35 @@ typedef struct st_print_event_info @section Log_event_binary_format Binary Format - Any Log_event saved on disk consists of the following three + Any @c Log_event saved on disk consists of the following three components. - @li Common-Header - @li Post-Header - @li Body + * Common-Header + * Post-Header + * Body - The Common-Header, documented below, always has the same form and - length within one version of MySQL. Each event type specifies a - form and length of the Post-Header common to all events of the type. - The Body may be of different form and length even for different - events of the same type. The binary formats of Post-Header and Body - are documented separately in each subclass. The binary format of - Common-Header is as follows. + The Common-Header, documented in the table @ref Table_common_header + "below", always has the same form and length within one version of + MySQL. Each event type specifies a form and length of the + Post-Header common to all events of the type. The Body may be of + different form and length even for different events of the same + type. The binary formats of Post-Header and Body are documented + separately in each subclass. The binary format of Common-Header is + as follows. - + - @@ -705,14 +706,14 @@ typedef struct st_print_event_info - - + + - + @@ -720,9 +721,12 @@ typedef struct st_print_event_info - + @@ -736,13 +740,55 @@ typedef struct st_print_event_info Summing up the numbers above, we see that the total size of the common header is 19 bytes. - @subsection Log_event_endianness_and_string_formats Endianness and String Formats + @subsection Log_event_format_of_atomic_primitives Format of Atomic Primitives - All numbers, whether they are 16-, 32-, or 64-bit, are stored in - little endian, i.e., the least significant byte first. + - All numbers, whether they are 16-, 24-, 32-, or 64-bit numbers, + are stored in little endian, i.e., the least significant byte first, + unless otherwise specified. - Strings are stored in various formats. The format of each string is - documented separately. + @anchor packed_integer + - Some events use a special format for efficient representation of + unsigned integers, called Packed Integer. A Packed Integer has the + capacity of storing up to 8-byte integers, while small integers + still can use 1, 3, or 4 bytes. The first byte indicates how many + bytes are used by the integer, according to the following table: + +
Common-Header
NameFormat
Format Description
timestamp 4 byte unsigned integerThe number of seconds since 1970. + The time when the query started, in seconds since 1970.
master_id4 byte integerserver_id4 byte unsigned integer Server ID of the server that created the event.
total_size4 byte integer4 byte unsigned integer The total size of this event, in bytes. In other words, this is the sum of the sizes of Common-Header, Post-Header, and Body.
master_position4 byte integer4 byte unsigned integer The position of the next event in the master binary log, in - bytes from the beginning of the file. + bytes from the beginning of the file. In a binlog that is not a + relay log, this is just the position of the next event, in bytes + from the beginning of the file. In a relay log, this is + the position of the next event in the master's binlog.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Format of Packed Integer
First byteFormat
0-250The first byte is the number (in range 0-250), and no more + bytes are used.
252Two more bytes are used. The number is in the range + 251-0xffff.
253Three more bytes are used. The number is in the range + 0xffff-0xffffff.
254Eight more bytes are used. The number is in the range + 0xffffff-0xffffffffffffffff.
+ + - Strings are stored in various formats. The format of each string + is documented separately. */ class Log_event { @@ -1123,7 +1169,8 @@ protected: /** @class Query_log_event - Logs SQL queries. + A @c Query_log_event is created for each query that modifies the + database, unless the query is logged row-based. @section Query_log_event_binary_format Binary format @@ -1134,60 +1181,49 @@ protected: Name - Size
+ Format Description slave_proxy_id 4 byte unsigned integer - An integer identifying the client thread, which is unique on - the server. (Note, however, that two threads on different servers - may have the same slave_proxy_id.) This is used when a client - thread creates a temporary table. Temporary tables are local to - the client, and the slave_proxy_id is used to distinguish - temporary tables belonging to different clients. + An integer identifying the client thread that issued the + query. The id is unique per server. (Note, however, that two + threads on different servers may have the same slave_proxy_id.) + This is used when a client thread creates a temporary table local + to the client. The slave_proxy_id is used to distinguish + temporary tables that belong to different clients. exec_time - 4 byte integer - ???TODO + 4 byte unsigned integer + The time from when the query started to when it was logged in + the binlog, in seconds. db_len 1 byte integer - The length of the name of the currently selected - database. - + The length of the name of the currently selected database. error_code - 2 byte integer + 2 byte unsigned integer Error code generated by the master. If the master fails, the slave will fail with the same error code, except for the error - codes ER_DB_CREATE_EXISTS==1007 and ER_DB_DROP_EXISTS==1008. + codes ER_DB_CREATE_EXISTS == 1007 and ER_DB_DROP_EXISTS == 1008. status_vars_len - 2 byte integer + 2 byte unsigned integer The length of the status_vars block of the Body, in bytes. See - below. - - - - - Post-Header-For-Derived - 0 bytes - This field is only written by the subclass - Execute_load_query_log_event. In this base class, it takes 0 - bytes. See separate documentation for - Execute_load_query_log_event. + @ref query_log_event_status_vars "below". @@ -1199,19 +1235,19 @@ protected: Name - Size
+ Format Description - status_vars - variable length + @anchor query_log_event_status_vars status_vars + status_vars_len bytes Zero or more status variables. Each status variable consists of one byte identifying the variable stored, followed by the value of the variable. The possible variables are listed separately in - the table below. MySQL always writes events in the order defined - below; however, it is capable of reading them in any order. - + the table @ref Table_query_log_event_status_vars "below". MySQL + always writes events in the order defined below; however, it is + capable of reading them in any order. @@ -1237,13 +1273,14 @@ protected: The following table lists the status variables that may appear in the status_vars field. + @anchor Table_query_log_event_status_vars - - + + @@ -1251,13 +1288,13 @@ protected: - - - + @@ -1327,7 +1364,7 @@ protected: @@ -1351,14 +1388,14 @@ protected: - + @@ -1409,14 +1446,14 @@ protected: - + @@ -1717,26 +1755,27 @@ private: - + - - + @@ -1773,7 +1812,7 @@ private: - + @@ -1813,7 +1852,7 @@ private:
  • In the old format, we know that each string has length 0 or 1. Therefore, only the first byte of each string is stored. The order of the strings is the same as in the new format. These five - bytes are followed by the same 1-byte bitfield as in the new + bytes are followed by the same 1 byte bitfield as in the new format. Finally, a 1 byte bitfield called empty_flags is stored. The low 5 bits of empty_flags indicate which of the five strings have length 0. For each of the following flags that is set, the @@ -1831,7 +1870,7 @@ private:
  • - + @@ -1992,11 +2031,13 @@ extern char server_version[SERVER_VERSION_LENGTH]; Start_log_event_v3 is the Start_log_event of binlog format 3 (MySQL 3.23 and 4.x). - Format_description_log_event derives from Start_log_event_v3; it is the - Start_log_event of binlog format 4 (MySQL 5.0), that is, the event that - describes the other events' header/postheader lengths. This event is sent by - MySQL 5.0 whenever it starts sending a new binlog if the requested position - is >4 (otherwise if ==4 the event will be sent naturally). + + Format_description_log_event derives from Start_log_event_v3; it is + the Start_log_event of binlog format 4 (MySQL 5.0), that is, the + event that describes the other events' Common-Header/Post-Header + lengths. This event is sent by MySQL 5.0 whenever it starts sending + a new binlog if the requested position is >4 (otherwise if ==4 the + event will be sent naturally). @section Start_log_event_v3_binary_format Binary Format */ @@ -2150,7 +2191,9 @@ protected: /** @class Intvar_log_event - Logs special variables related to auto_increment values. + An Intvar_log_event will be created just before a Query_log_event, + if the query uses one of the variables LAST_INSERT_ID or INSERT_ID. + Each Intvar_log_event holds the value of one of these variables. @section Intvar_log_event_binary_format Binary Format @@ -2161,12 +2204,12 @@ protected: - + - +
    Status variables for Query_log_event
    Status variable1-byte identifierSize
    1 byte identifierFormat Description
    flags2 Q_FLAGS2_CODE == 0 4 byte bitfieldThe flags in thd->options, binary AND-ed with - OPTIONS_WRITTEN_TO_BIN_LOG. The thd->options bitfield contains - options for SELECT. OPTIONS_WRITTEN identifies those options that - need to be written to the binlog (not all do). Specifically, - OPTIONS_WRITTEN_TO_BIN_LOG equals (OPTION_AUTO_IS_NULL | - OPTION_NO_FOREIGN_KEY_CHECKS | OPTION_RELAXED_UNIQUE_CHECKS | - OPTION_NOT_AUTOCOMMIT), or 0x0c084000 in hex. + The flags in @c thd->options, binary AND-ed with @c + OPTIONS_WRITTEN_TO_BIN_LOG. The @c thd->options bitfield contains + options for "SELECT". @c OPTIONS_WRITTEN identifies those options + that need to be written to the binlog (not all do). Specifically, + @c OPTIONS_WRITTEN_TO_BIN_LOG equals (@c OPTION_AUTO_IS_NULL | @c + OPTION_NO_FOREIGN_KEY_CHECKS | @c OPTION_RELAXED_UNIQUE_CHECKS | + @c OPTION_NOT_AUTOCOMMIT), or 0x0c084000 in hex. These flags correspond to the SQL variables SQL_AUTO_IS_NULL, FOREIGN_KEY_CHECKS, UNIQUE_CHECKS, and AUTOCOMMIT, documented in @@ -1271,8 +1308,8 @@ protected:
    sql_mode Q_SQL_MODE_CODE == 18 byte integerThe sql_mode variable. See the section "SQL Modes" in the + 8 byte bitfieldThe @c sql_mode variable. See the section "SQL Modes" in the MySQL manual, and see mysql_priv.h for a list of the possible flags. Currently (2007-10-04), the following flags are available:
    @@ -1310,10 +1347,10 @@ protected:
         MODE_PAD_CHAR_TO_FULL_LENGTH==0x80000000
         
    All these flags are replicated from the server. However, all - flags except MODE_NO_DIR_IN_CREATE are honored by the slave; the - slave always preserves its old value of MODE_NO_DIR_IN_CREATE. - For a rationale, see comment in Query_log_event::do_apply_event in - log_event.cc. + flags except @c MODE_NO_DIR_IN_CREATE are honored by the slave; + the slave always preserves its old value of @c + MODE_NO_DIR_IN_CREATE. For a rationale, see comment in + @c Query_log_event::do_apply_event in @c log_event.cc. This field is always written to the binlog.
    Stores the client's current catalog. Every database belongs to a catalog, the same way that every table belongs to a - database. Currently, there is only one catalog, 'std'. + database. Currently, there is only one catalog, "std". This field is written if the length of the catalog is > 0; otherwise it is not written. @@ -1343,7 +1380,7 @@ protected: auto_increment_offset, in that order. For more information, see "System variables" in the MySQL manual. - This field is written if auto_increment>1; otherwise it is not + This field is written if auto_increment > 1. Otherwise, it is not written.
    charset Q_CHARSET_CODE == 4three 2-byte unsigned integers (i.e., 6 bytes)three 2 byte unsigned integers, totally 2+2+2=6 bytes The three variables character_set_client, collation_connection, and collation_server, in that order. - `character_set_client' is a code identifying the character set and + character_set_client is a code identifying the character set and collation used by the client to encode the query. - `collation_connection' identifies the character set and collation + collation_connection identifies the character set and collation that the master converts the query to when it receives it; this is - useful when comparing literal strings. `collation_server' is the + useful when comparing literal strings. collation_server is the default character set and collation used when a new database is created. @@ -1396,9 +1433,9 @@ protected: Q_LC_TIME_NAMES_CODE == 7 2 byte integer A code identifying a table of month and day names. The - mapping from codes to languages is defined in sql_locale.cc. + mapping from codes to languages is defined in @c sql_locale.cc. - This field is written if it is != 0, i.e., if the locale is not + This field is written if it is not 0, i.e., if the locale is not en_US.
    2 byte integer The value of the collation_database system variable (in the - source code stored in thd->variables.collation_database), which + source code stored in @c thd->variables.collation_database), which holds the code for a (character set, collation) pair as described above (see Q_CHARSET_CODE). - `collation_database' was used in old versions (???WHEN). Its - value was loaded when issuing a "use db" command and could be - changed by issuing a "SET collation_database=xxx" command. It - used to affect the "LOAD DATA INFILE" and "CREATE TABLE" commands. + collation_database was used in old versions (???WHEN). Its value + was loaded when issuing a "use db" query and could be changed by + issuing a "SET collation_database=xxx" query. It used to affect + the "LOAD DATA INFILE" and "CREATE TABLE" commands. In newer versions, "CREATE TABLE" has been changed to take the character set from the database of the created table, rather than @@ -1433,17 +1470,17 @@ protected: @subsection Query_log_event_notes_on_previous_versions Notes on Previous Versions - @li Status vars were introduced in version 5.0. To read earlier + * Status vars were introduced in version 5.0. To read earlier versions correctly, check the length of the Post-Header. - @li The status variable Q_CATALOG_CODE == 2 existed in MySQL 5.0.x, + * The status variable Q_CATALOG_CODE == 2 existed in MySQL 5.0.x, where 0<=x<=3. It was identical to Q_CATALOG_CODE, except that the string had a trailing '\0'. The '\0' was removed in 5.0.4 since it was redundant (the string length is stored before the string). The Q_CATALOG_CODE will never be written by a new master, but can still be understood by a new slave. - @li See Q_CHARSET_DATABASE_NUMBER in the table above. + * See Q_CHARSET_DATABASE_NUMBER in the table above. */ class Query_log_event: public Log_event @@ -1576,7 +1613,8 @@ public: /* !!! Public in this patch to allow old usage */ /** @class Muted_query_log_event - Pretends to log SQL queries, but doesn't actually do so. + Pretends to log SQL queries, but doesn't actually do so. This is + used internally only and never written to any binlog. @section Muted_query_log_event_binary_format Binary Format @@ -1603,7 +1641,7 @@ public: @class Slave_log_event Note that this class is currently not used at all; no code writes a - Slave_log_event (though some code in repl_failsafe.cc reads + @c Slave_log_event (though some code in @c repl_failsafe.cc reads @c Slave_log_event). So it's not a problem if this code is not maintained. @@ -1617,7 +1655,7 @@ public:
    NameSize
    Format Description
    NameSize
    Format Description
    slave_proxy_id 4 byte unsigned integerAn integer identifying the client thread, which is unique on - the server. (Note, however, that the same slave_proxy_id may - appear on different servers.) This is used when a client thread - creates a temporary table. Temporary tables are local to the - client, and the slave_proxy_id is used to distinguish temporary - tables belonging to different clients. + An integer identifying the client thread that issued the + query. The id is unique per server. (Note, however, that two + threads on different servers may have the same slave_proxy_id.) + This is used when a client thread creates a temporary table local + to the client. The slave_proxy_id is used to distinguish + temporary tables that belong to different clients.
    exec_time 4 byte unsigned integer???TODOThe time from when the query started to when it was logged in + the binlog, in seconds.
    NameSize
    Format Description
    field_lensnum_fields 1-byte unsigned integersnum_fields 1 byte unsigned integers An array of num_fields integers representing the length of each field in the query. (num_fields is from the Post-Header).
    NameSize
    Format Description
    Typetype 1 byte enumeration One byte identifying the type of variable stored. Currently, two identifiers are supported: LAST_INSERT_ID_EVENT==1 and @@ -2182,7 +2225,6 @@ protected:
    */ - class Intvar_log_event: public Log_event { public: @@ -2228,15 +2270,34 @@ private: written in 4.1.1 for PASSWORD() (but the fact that it is written is just a waste, it does not cause bugs). + The state of the random number generation consists of 128 bits, + which are stored internally as two 64-bit numbers. + @section Rand_log_event_binary_format Binary Format This event type has no Post-Header. The Body of this event type has two components: - @li seed1 (8 bytes): 64 bit random seed1. - @li seed2 (8 bytes): 64 bit random seed2. + + - The state of the random number generation consists of 128 bits, - which are stored internally as two 64-bit numbers. + + + + + + + + + + + + + + + + + +
    Post-Header for Intvar_log_event
    NameFormatDescription
    seed18 byte unsigned integer64 bit random seed1.
    seed28 byte unsigned integer64 bit random seed2.
    */ class Rand_log_event: public Log_event @@ -2423,14 +2484,14 @@ private: Name - Size
    + Format Description - pos + position 8 byte integer - ???TODO + The position within the binlog to rotate to. @@ -2442,17 +2503,17 @@ private: Name - Size
    + Format Description - new_log_ident + new_log variable length string without trailing zero, extending to the end of the event (determined by the length field of the Common-Header) - ???TODO + Name of the binlog to rotate to. @@ -2841,10 +2902,316 @@ char *str_to_hex(char *to, const char *from, uint len); /** @class Table_map_log_event - Create a mapping from a (database name, table name) couple to a table - identifier (an integer number). + In row-based mode, every row operation event is preceded by a + Table_map_log_event which maps a table definition to a number. The + table definition consists of database name, table name, and column + definitions. @section Table_map_log_event_binary_format Binary Format + + The Post-Header has the following components: + + + + + + + + + + + + + + + + + + + + + + +
    Post-Header for Table_map_log_event
    NameFormatDescription
    table_id6 bytes unsigned integerThe number that identifies the table.
    flags2 byte bitfieldReserved for future use; currently always 0.
    + + The Body has the following components: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Body for Table_map_log_event
    NameFormatDescription
    database_nameone byte string length, followed by null-terminated stringThe name of the database in which the table resides. The name + is represented as a one byte unsigned integer representing the + number of bytes in the name, followed by length bytes containing + the database name, followed by a terminating 0 byte. (Note the + redundancy in the representation of the length.)
    table_nameone byte string length, followed by null-terminated stringThe name of the table, encoded the same way as the database + name above.
    column_count@ref packed_integer "Packed Integer"The number of columns in the table, represented as a packed + variable-length integer.
    column_typeList of column_count 1 byte enumeration valuesThe type of each column in the table, listed from left to + right. Each byte is mapped to a column type according to the + enumeration type enum_field_types defined in mysql_com.h. The + mapping of types to numbers is listed in the table @ref + Table_table_map_log_event_column_types "below" (along with + description of the associated metadata field).
    metadata_length@ref packed_integer "Packed Integer"The length of the following metadata block
    metadatalist of metadata for each columnFor each column from left to right, a chunk of data who's + length and semantics depends on the type of the column. The + length and semantics for the metadata for each column are listed + in the table @ref Table_table_map_log_event_column_types + "below".
    null_bitscolumn_count bits, rounded up to nearest byteFor each column, a bit indicating whether data in the column + can be NULL or not. The number of bytes needed for this is + int((column_count+7)/8). The flag for the first column from the + left is in the least-significant bit of the first byte, the second + is in the second least significant bit of the first byte, the + ninth is in the least significant bit of the second byte, and so + on.
    + + The table below lists all column types, along with the numerical + identifier for it and the size and interpretation of meta-data used + to describe the type. + + @anchor Table_table_map_log_event_column_types + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table_map_log_event column types: numerical identifier and + metadata
    NameIdentifierSize of metadata in bytesDescription of metadata
    MYSQL_TYPE_DECIMAL00No column metadata.
    MYSQL_TYPE_TINY10No column metadata.
    MYSQL_TYPE_SHORT20No column metadata.
    MYSQL_TYPE_LONG30No column metadata.
    MYSQL_TYPE_FLOAT41 byte1 byte unsigned integer, representing the "pack_length", which + is equal to sizeof(float) on the server from which the event + originates.
    MYSQL_TYPE_DOUBLE51 byte1 byte unsigned integer, representing the "pack_length", which + is equal to sizeof(double) on the server from which the event + originates.
    MYSQL_TYPE_NULL60No column metadata.
    MYSQL_TYPE_TIMESTAMP70No column metadata.
    MYSQL_TYPE_LONGLONG80No column metadata.
    MYSQL_TYPE_INT2490No column metadata.
    MYSQL_TYPE_DATE100No column metadata.
    MYSQL_TYPE_TIME110No column metadata.
    MYSQL_TYPE_DATETIME120No column metadata.
    MYSQL_TYPE_YEAR130No column metadata.
    MYSQL_TYPE_NEWDATE14This enumeration value is only used internally and cannot + exist in a binlog.
    MYSQL_TYPE_VARCHAR152 bytes2 byte unsigned integer representing the maximum length of + the string.
    MYSQL_TYPE_BIT162 bytesA 1 byte unsigned int representing the length in bits of the + bitfield (0 to 64), followed by a 1 byte unsigned int + representing the number of bytes occupied by the bitfield. The + number of bytes is either int((length+7)/8) or int(length/8).
    MYSQL_TYPE_NEWDECIMAL2462 bytesA 1 byte unsigned int representing the precision, followed + by a 1 byte unsigned int representing the number of decimals.
    MYSQL_TYPE_ENUM247This enumeration value is only used internally and cannot + exist in a binlog.
    MYSQL_TYPE_SET248This enumeration value is only used internally and cannot + exist in a binlog.
    MYSQL_TYPE_TINY_BLOB249This enumeration value is only used internally and cannot + exist in a binlog.
    MYSQL_TYPE_MEDIUM_BLOB250This enumeration value is only used internally and cannot + exist in a binlog.
    MYSQL_TYPE_LONG_BLOB251This enumeration value is only used internally and cannot + exist in a binlog.
    MYSQL_TYPE_BLOB2521 byteThe pack length, i.e., the number of bytes needed to represent + the length of the blob: 1, 2, 3, or 4.
    MYSQL_TYPE_VAR_STRING2532 bytesThis is used to store both strings and enumeration values. + The first byte is a enumeration value storing the real + type, which may be either MYSQL_TYPE_VAR_STRING or + MYSQL_TYPE_ENUM. The second byte is a 1 byte unsigned integer + representing the field size, i.e., the number of bytes needed to + store the length of the string.
    MYSQL_TYPE_STRING2542 bytesThe first byte is always MYSQL_TYPE_VAR_STRING (i.e., 253). + The second byte is the field size, i.e., the number of bytes in + the representation of size of the string: 3 or 4.
    MYSQL_TYPE_GEOMETRY2551 byteThe pack length, i.e., the number of bytes needed to represent + the length of the geometry: 1, 2, 3, or 4.
    */ class Table_map_log_event : public Log_event { @@ -3131,6 +3498,8 @@ protected: ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT); int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols, &m_curr_row_end, &m_master_reclength); + if (m_curr_row_end > m_rows_end) + my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0)); ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT); return result; } @@ -3408,7 +3777,7 @@ protected: Incident event format Symbol - Size
    (bytes) + Format Description diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 7621bdc6291..13f9763debe 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -2078,7 +2078,7 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli, /* fill table->record[0] with default values */ - if ((error= prepare_record(rli, table, m_width, + if ((error= prepare_record(table, m_width, TRUE /* check if columns have def. values */))) DBUG_RETURN(error); @@ -2289,7 +2289,7 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) /* unpack row - missing fields get default values */ // TODO: shall we check and report errors here? - prepare_record(NULL,table,m_width,FALSE /* don't check errors */); + prepare_record(table, m_width, FALSE /* don't check errors */); error= unpack_current_row(rli); #ifndef DBUG_OFF diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f1a594351bc..ea552414d9a 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1034,7 +1034,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, bool check_access(THD *thd, ulong access, const char *db, ulong *save_priv, bool no_grant, bool no_errors, bool schema_db); bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables, - bool no_errors); + uint number, bool no_errors); bool check_global_access(THD *thd, ulong want_access); #else inline bool check_access(THD *thd, ulong access, const char *db, @@ -1046,7 +1046,7 @@ inline bool check_access(THD *thd, ulong access, const char *db, return false; } inline bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables, - bool no_errors) + uint number, bool no_errors) { return false; } inline bool check_global_access(THD *thd, ulong want_access) { return false; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 61f3735fe62..08ecc025332 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -221,6 +221,11 @@ extern "C" int gethostname(char *name, int namelen); /* Constants */ const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"}; +/* + WARNING: When adding new SQL modes don't forget to update the + tables definitions that stores it's value. + (ie: mysql.event, mysql.proc) +*/ static const char *sql_mode_names[]= { "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", @@ -2179,6 +2184,16 @@ static void check_data_home(const char *path) #define UNSAFE_DEFAULT_LINUX_THREADS 200 #endif + +#if BACKTRACE_DEMANGLE +#include +extern "C" char *my_demangle(const char *mangled_name, int *status) +{ + return abi::__cxa_demangle(mangled_name, NULL, NULL, status); +} +#endif + + extern "C" sig_handler handle_segfault(int sig) { time_t curr_time; @@ -2250,10 +2265,29 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n", } if (thd) { + const char *kreason= "UNKNOWN"; + switch (thd->killed) { + case THD::NOT_KILLED: + kreason= "NOT_KILLED"; + break; + case THD::KILL_BAD_DATA: + kreason= "KILL_BAD_DATA"; + break; + case THD::KILL_CONNECTION: + kreason= "KILL_CONNECTION"; + break; + case THD::KILL_QUERY: + kreason= "KILL_QUERY"; + break; + case THD::KILLED_NO_VALUE: + kreason= "KILLED_NO_VALUE"; + break; + } fprintf(stderr, "Trying to get some variables.\n\ Some pointers may be invalid and cause the dump to abort...\n"); safe_print_str("thd->query", thd->query, 1024); fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id); + fprintf(stderr, "thd->killed=%s\n", kreason); } fprintf(stderr, "\ The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\ diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index eb32897f937..7c74dcba5a0 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -307,17 +307,15 @@ unpack_row(Relay_log_info const *rli, If @c check is true, fields are explicitly initialized only if they have default value or can be NULL. Otherwise error is reported. - @param log Used to report errors. @param table Table whose record[0] buffer is prepared. @param skip Number of columns for which default value initialization should be skipped. @param check Indicates if errors should be checked when setting default values. - @returns 0 on success. + @returns 0 on success or a handler level error code */ -int prepare_record(const Slave_reporting_capability *const log, - TABLE *const table, +int prepare_record(TABLE *const table, const uint skip, const bool check) { DBUG_ENTER("prepare_record"); @@ -337,14 +335,8 @@ int prepare_record(const Slave_reporting_capability *const log, if (check && ((f->flags & mask) == mask)) { - DBUG_ASSERT(log); - error= ER_NO_DEFAULT_FOR_FIELD; - log->report(ERROR_LEVEL, error, - "Field `%s` of table `%s`.`%s` " - "has no default value and cannot be NULL", - f->field_name, table->s->db.str, - table->s->table_name.str); - my_error(error, MYF(0), f->field_name); + my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), f->field_name); + error = HA_ERR_ROWS_EVENT_APPLY; } else f->set_default(); diff --git a/sql/rpl_record.h b/sql/rpl_record.h index 0d6ceda7433..f9e64f0ab1d 100644 --- a/sql/rpl_record.h +++ b/sql/rpl_record.h @@ -30,8 +30,7 @@ int unpack_row(Relay_log_info const *rli, uchar const **const row_end, ulong *const master_reclength); // Fill table's record[0] with default values. -int prepare_record(const Slave_reporting_capability *const, TABLE *const, - const uint =0, const bool =FALSE); +int prepare_record(TABLE *const, const uint =0, const bool =FALSE); #endif #endif diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 3e9a484126a..03f790b934f 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -33,7 +33,10 @@ Relay_log_info::Relay_log_info() :Slave_reporting_capability("SQL"), no_storage(FALSE), replicate_same_server_id(::replicate_same_server_id), info_fd(-1), cur_log_fd(-1), save_temporary_tables(0), - group_relay_log_pos(0), + group_relay_log_pos(0), event_relay_log_pos(0), +#if HAVE_purify + is_fake(FALSE), +#endif cur_log_old_open_count(0), group_master_log_pos(0), log_space_total(0), ignore_log_space_limit(0), last_master_timestamp(0), slave_skip_counter(0), abort_pos_wait(0), slave_run_id(0), sql_thd(0), diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index a3a57ad4ce9..36daffae1af 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -154,6 +154,10 @@ public: ulonglong event_relay_log_pos; ulonglong future_event_relay_log_pos; +#ifdef HAVE_purify + bool is_fake; /* Mark that this is a fake relay log info structure */ +#endif + /* Original log name and position of the group we're currently executing (whose coordinates are group_relay_log_name/pos in the relay log) diff --git a/sql/set_var.cc b/sql/set_var.cc index 410608f154f..4c77cbfff82 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1021,7 +1021,7 @@ bool sys_var_set::update(THD *thd, set_var *var) { *value= var->save_result.ulong_value; return 0; -}; +} uchar *sys_var_set::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base) diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 026a0023660..ee3a7e6080a 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -6119,3 +6119,5 @@ ER_SLAVE_AMBIGOUS_EXEC_MODE ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT eng "The BINLOG statement of type `%s` was not preceded by a format description BINLOG statement." +ER_SLAVE_CORRUPT_EVENT + eng "Corrupted replication event was detected" diff --git a/sql/slave.cc b/sql/slave.cc index 4ffc2023e85..ea0dde942da 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1337,14 +1337,15 @@ bool show_master_info(THD* thd, Master_info* mi) protocol->prepare_for_resend(); /* - TODO: we read slave_running without run_lock, whereas these variables - are updated under run_lock and not data_lock. In 5.0 we should lock - run_lock on top of data_lock (with good order). + slave_running can be accessed without run_lock but not other + non-volotile members like mi->io_thd, which is guarded by the mutex. */ + pthread_mutex_lock(&mi->run_lock); + protocol->store(mi->io_thd ? mi->io_thd->proc_info : "", &my_charset_bin); + pthread_mutex_unlock(&mi->run_lock); + pthread_mutex_lock(&mi->data_lock); pthread_mutex_lock(&mi->rli.data_lock); - - protocol->store(mi->io_thd ? mi->io_thd->proc_info : "", &my_charset_bin); protocol->store(mi->host, &my_charset_bin); protocol->store(mi->user, &my_charset_bin); protocol->store((uint32) mi->port); @@ -1892,14 +1893,21 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli, if (exec_res == 0) { int error= ev->update_pos(rli); - char buf[22]; - DBUG_PRINT("info", ("update_pos error = %d", error)); - DBUG_PRINT("info", ("group %s %s", - llstr(rli->group_relay_log_pos, buf), - rli->group_relay_log_name)); - DBUG_PRINT("info", ("event %s %s", - llstr(rli->event_relay_log_pos, buf), - rli->event_relay_log_name)); +#ifdef HAVE_purify + if (!rli->is_fake) +#endif + { +#ifndef DBUG_OFF + char buf[22]; +#endif + DBUG_PRINT("info", ("update_pos error = %d", error)); + DBUG_PRINT("info", ("group %s %s", + llstr(rli->group_relay_log_pos, buf), + rli->group_relay_log_name)); + DBUG_PRINT("info", ("event %s %s", + llstr(rli->event_relay_log_pos, buf), + rli->event_relay_log_name)); + } /* The update should not fail, so print an error message and return an error code. @@ -1909,6 +1917,7 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli, */ if (error) { + char buf[22]; rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR, "It was not possible to update the positions" " of the relay log information: the slave may" diff --git a/sql/slave.h b/sql/slave.h index f1772bbc1fc..b4f1b7f7467 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -80,8 +80,8 @@ class Master_info; mi->rli does not either. In Master_info: run_lock, data_lock - run_lock protects all information about the run state: slave_running, and the - existence of the I/O thread (to stop/start it, you need this mutex). + run_lock protects all information about the run state: slave_running, thd + and the existence of the I/O thread to stop/start it, you need this mutex). data_lock protects some moving members of the struct: counters (log name, position) and relay log (MYSQL_BIN_LOG object). diff --git a/sql/sp.cc b/sql/sp.cc index 99ffc18deea..83995e9b753 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -388,7 +388,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) uint length; char buff[65]; String str(buff, sizeof(buff), &my_charset_bin); - ulong sql_mode; + ulong sql_mode, saved_mode= thd->variables.sql_mode; Open_tables_state open_tables_state_backup; Stored_program_creation_ctx *creation_ctx; @@ -400,6 +400,9 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) if (!(table= open_proc_table_for_read(thd, &open_tables_state_backup))) DBUG_RETURN(SP_OPEN_TABLE_FAILED); + /* Reset sql_mode during data dictionary operations. */ + thd->variables.sql_mode= 0; + if ((ret= db_find_routine_aux(thd, type, name, table)) != SP_OK) goto done; @@ -503,10 +506,36 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) done: if (table) close_system_tables(thd, &open_tables_state_backup); + thd->variables.sql_mode= saved_mode; DBUG_RETURN(ret); } +/** + Silence DEPRECATED SYNTAX warnings when loading a stored procedure + into the cache. +*/ +struct Silence_deprecated_warning : public Internal_error_handler +{ +public: + virtual bool handle_error(uint sql_errno, const char *message, + MYSQL_ERROR::enum_warning_level level, + THD *thd); +}; + +bool +Silence_deprecated_warning::handle_error(uint sql_errno, const char *message, + MYSQL_ERROR::enum_warning_level level, + THD *thd) +{ + if (sql_errno == ER_WARN_DEPRECATED_SYNTAX && + level == MYSQL_ERROR::WARN_LEVEL_WARN) + return TRUE; + + return FALSE; +} + + static int db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, ulong sql_mode, const char *params, const char *returns, @@ -523,7 +552,8 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, ulong old_sql_mode= thd->variables.sql_mode; ha_rows old_select_limit= thd->variables.select_limit; sp_rcontext *old_spcont= thd->spcont; - + Silence_deprecated_warning warning_handler; + char definer_user_name_holder[USERNAME_LENGTH + 1]; LEX_STRING definer_user_name= { definer_user_name_holder, USERNAME_LENGTH }; @@ -583,7 +613,9 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, lex_start(thd); + thd->push_internal_handler(&warning_handler); ret= parse_sql(thd, &lip, creation_ctx) || newlex.sphead == NULL; + thd->pop_internal_handler(); /* Force switching back to the saved current database (if changed), @@ -675,6 +707,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) int ret; TABLE *table; char definer[USER_HOST_BUFF_SIZE]; + ulong saved_mode= thd->variables.sql_mode; CHARSET_INFO *db_cs= get_default_db_collation(thd, sp->m_db.str); @@ -689,6 +722,9 @@ sp_create_routine(THD *thd, int type, sp_head *sp) DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE || type == TYPE_ENUM_FUNCTION); + /* Reset sql_mode during data dictionary operations. */ + thd->variables.sql_mode= 0; + /* This statement will be replicated as a statement, even when using row-based replication. The flag will be reset at the end of the @@ -790,7 +826,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) store_failed= store_failed || table->field[MYSQL_PROC_FIELD_SQL_MODE]-> - store((longlong)thd->variables.sql_mode, TRUE); + store((longlong)saved_mode, TRUE); if (sp->m_chistics->comment.str) { @@ -890,6 +926,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) done: thd->count_cuted_fields= saved_count_cuted_fields; + thd->variables.sql_mode= saved_mode; close_thread_tables(thd); DBUG_RETURN(ret); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 0edb566ed9f..8e6f5a96640 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2309,7 +2309,7 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access) bzero((char*) &tables,sizeof(tables)); tables.db= (char*) "mysql"; tables.table_name= tables.alias= (char*) "proc"; - *full_access= (!check_table_access(thd, SELECT_ACL, &tables, 1) || + *full_access= (!check_table_access(thd, SELECT_ACL, &tables, 1, TRUE) || (!strcmp(sp->m_definer_user.str, thd->security_ctx->priv_user) && !strcmp(sp->m_definer_host.str, @@ -2753,7 +2753,7 @@ int sp_instr::exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables) Check whenever we have access to tables for this statement and open and lock them before executing instructions core function. */ - if (check_table_access(thd, SELECT_ACL, tables, 0) + if (check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE) || open_and_lock_tables(thd, tables)) result= -1; else diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 0d563ab9051..b04f624f746 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3041,6 +3041,12 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, } #endif + /* + The lock api is depending on the thd->lex variable which needs to be + re-initialized. + */ + Query_tables_list backup; + thd->lex->reset_n_backup_query_tables_list(&backup); if (simple_open_n_lock_tables(thd,tables)) { // Should never happen close_thread_tables(thd); /* purecov: deadcode */ @@ -3173,6 +3179,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, send_ok(thd); /* Tables are automatically closed */ + thd->lex->restore_backup_query_tables_list(&backup); DBUG_RETURN(result); } @@ -3862,7 +3869,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, of other queries). For simple queries first_not_own_table is 0. */ for (i= 0, table= tables; - table != first_not_own_table && i < number; + i < number && table != first_not_own_table; table= table->next_global, i++) { /* Remove SHOW_VIEW_ACL, because it will be checked during making view */ diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 799cb673a0e..e5a5b51fcf6 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -799,7 +799,7 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild) table_list.table_name= share->table_name.str; table_list.grant.privilege=0; - if (check_table_access(thd,SELECT_ACL | EXTRA_ACL,&table_list,1)) + if (check_table_access(thd,SELECT_ACL | EXTRA_ACL,&table_list, 1, TRUE)) continue; /* need to check if we haven't already listed it */ for (table= open_list ; table ; table=table->next) diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc index 04f408453ea..cff4ceeccf9 100644 --- a/sql/sql_binlog.cc +++ b/sql/sql_binlog.cc @@ -56,6 +56,9 @@ void mysql_client_binlog_statement(THD* thd) if (!thd->rli_fake) { thd->rli_fake= new Relay_log_info; +#ifdef HAVE_purify + thd->rli_fake->is_fake= TRUE; +#endif have_fd_event= FALSE; } if (thd->rli_fake && !thd->rli_fake->relay_log.description_event_for_exec) @@ -152,14 +155,13 @@ void mysql_client_binlog_statement(THD* thd) */ if (!have_fd_event) { - if (bufptr[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) + int type = bufptr[EVENT_TYPE_OFFSET]; + if (type == FORMAT_DESCRIPTION_EVENT || type == START_EVENT_V3) have_fd_event= TRUE; else { my_error(ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT, - MYF(0), - Log_event::get_type_str( - (Log_event_type)bufptr[EVENT_TYPE_OFFSET])); + MYF(0), Log_event::get_type_str((Log_event_type)type)); goto end; } } diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h index 9a765120895..97accefe8aa 100644 --- a/sql/sql_bitmap.h +++ b/sql/sql_bitmap.h @@ -65,7 +65,7 @@ public: my_bool is_clear_all() const { return bitmap_is_clear_all(&map); } my_bool is_set_all() const { return bitmap_is_set_all(&map); } my_bool is_subset(const Bitmap& map2) const { return bitmap_is_subset(&map, &map2.map); } - my_bool is_overlapping(const Bitmap& map2) const { return bitmap_is_overlapping(&map, map2.map); } + my_bool is_overlapping(const Bitmap& map2) const { return bitmap_is_overlapping(&map, &map2.map); } my_bool operator==(const Bitmap& map2) const { return bitmap_cmp(&map, &map2.map); } char *print(char *buf) const { diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 7e54f87fe14..ae6765c7934 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1384,7 +1384,7 @@ def_week_frmt: %lu", table_list.db = table->db(); table_list.alias= table_list.table_name= table->table(); #ifndef NO_EMBEDDED_ACCESS_CHECKS - if (check_table_access(thd,SELECT_ACL,&table_list,1)) + if (check_table_access(thd,SELECT_ACL,&table_list, 1, TRUE)) { DBUG_PRINT("qcache", ("probably no SELECT access to %s.%s => return to normal processing", diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 75376c53f68..5180cafc774 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -406,7 +406,7 @@ Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg, m_affected_rows= affected_rows_arg; m_last_insert_id= last_insert_id_arg; if (message_arg) - strmake(m_message, message_arg, sizeof(m_message)); + strmake(m_message, message_arg, sizeof(m_message) - 1); else m_message[0]= '\0'; m_status= DA_OK; @@ -456,7 +456,7 @@ Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg, DBUG_ASSERT(! is_set() || can_overwrite_status); m_sql_errno= sql_errno_arg; - strmake(m_message, message_arg, sizeof(m_message)); + strmake(m_message, message_arg, sizeof(m_message) - 1); m_status= DA_ERROR; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1ae42b3ce79..55ae30d37ad 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -503,7 +503,7 @@ static bool check_merge_table_access(THD *thd, char *db, tlist->db= db; /* purecov: inspected */ } error= check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL, - table_list,0); + table_list, UINT_MAX, FALSE); } return error; } @@ -2046,7 +2046,7 @@ mysql_execute_command(THD *thd) res= check_table_access(thd, lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL, - all_tables, 0); + all_tables, UINT_MAX, FALSE); } else res= check_access(thd, @@ -2071,7 +2071,7 @@ mysql_execute_command(THD *thd) break; } case SQLCOM_DO: - if (check_table_access(thd, SELECT_ACL, all_tables, 0) || + if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) || open_and_lock_tables(thd, all_tables)) goto error; @@ -2181,7 +2181,7 @@ mysql_execute_command(THD *thd) case SQLCOM_BACKUP_TABLE: { DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, SELECT_ACL, all_tables, 0) || + if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) || check_global_access(thd, FILE_ACL)) goto error; /* purecov: inspected */ thd->enable_slow_log= opt_log_slow_admin_statements; @@ -2193,7 +2193,7 @@ mysql_execute_command(THD *thd) case SQLCOM_RESTORE_TABLE: { DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, INSERT_ACL, all_tables, 0) || + if (check_table_access(thd, INSERT_ACL, all_tables, UINT_MAX, FALSE) || check_global_access(thd, FILE_ACL)) goto error; /* purecov: inspected */ thd->enable_slow_log= opt_log_slow_admin_statements; @@ -2270,14 +2270,14 @@ mysql_execute_command(THD *thd) #endif /* HAVE_REPLICATION */ case SQLCOM_SHOW_ENGINE_STATUS: { - if (check_global_access(thd, SUPER_ACL)) + if (check_global_access(thd, PROCESS_ACL)) goto error; res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_STATUS); break; } case SQLCOM_SHOW_ENGINE_MUTEX: { - if (check_global_access(thd, SUPER_ACL)) + if (check_global_access(thd, PROCESS_ACL)) goto error; res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_MUTEX); break; @@ -2742,7 +2742,8 @@ end_with_restore_list: case SQLCOM_CHECKSUM: { DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, SELECT_ACL | EXTRA_ACL, all_tables, 0)) + if (check_table_access(thd, SELECT_ACL | EXTRA_ACL, all_tables, + UINT_MAX, FALSE)) goto error; /* purecov: inspected */ res = mysql_checksum_table(thd, first_table, &lex->check_opt); break; @@ -2750,7 +2751,8 @@ end_with_restore_list: case SQLCOM_REPAIR: { DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0)) + if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, + UINT_MAX, FALSE)) goto error; /* purecov: inspected */ thd->enable_slow_log= opt_log_slow_admin_statements; res= mysql_repair_table(thd, first_table, &lex->check_opt); @@ -2769,7 +2771,8 @@ end_with_restore_list: case SQLCOM_CHECK: { DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, SELECT_ACL | EXTRA_ACL , all_tables, 0)) + if (check_table_access(thd, SELECT_ACL | EXTRA_ACL , all_tables, + UINT_MAX, FALSE)) goto error; /* purecov: inspected */ thd->enable_slow_log= opt_log_slow_admin_statements; res = mysql_check_table(thd, first_table, &lex->check_opt); @@ -2780,7 +2783,8 @@ end_with_restore_list: case SQLCOM_ANALYZE: { DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0)) + if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, + UINT_MAX, FALSE)) goto error; /* purecov: inspected */ thd->enable_slow_log= opt_log_slow_admin_statements; res= mysql_analyze_table(thd, first_table, &lex->check_opt); @@ -2800,7 +2804,8 @@ end_with_restore_list: case SQLCOM_OPTIMIZE: { DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0)) + if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, + UINT_MAX, FALSE)) goto error; /* purecov: inspected */ thd->enable_slow_log= opt_log_slow_admin_statements; res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ? @@ -3129,7 +3134,7 @@ end_with_restore_list: DBUG_ASSERT(first_table == all_tables && first_table != 0); if (!lex->drop_temporary) { - if (check_table_access(thd, DROP_ACL, all_tables, 0)) + if (check_table_access(thd, DROP_ACL, all_tables, UINT_MAX, FALSE)) goto error; /* purecov: inspected */ if (end_active_trans(thd)) goto error; @@ -3233,7 +3238,7 @@ end_with_restore_list: if (lex->autocommit && end_active_trans(thd)) goto error; - if ((check_table_access(thd, SELECT_ACL, all_tables, 0) || + if ((check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) || open_and_lock_tables(thd, all_tables))) goto error; if (lex->one_shot_set && not_all_support_one_shot(lex_var_list)) @@ -3275,7 +3280,8 @@ end_with_restore_list: /* we must end the trasaction first, regardless of anything */ if (end_active_trans(thd)) goto error; - if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, 0)) + if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, + UINT_MAX, FALSE)) goto error; thd->in_lock_tables=1; thd->options|= OPTION_TABLE_LOCK; @@ -3769,7 +3775,7 @@ end_with_restore_list: #endif case SQLCOM_HA_OPEN: DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_table_access(thd, SELECT_ACL, all_tables, 0)) + if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)) goto error; res= mysql_ha_open(thd, first_table, 0); break; @@ -4017,7 +4023,7 @@ create_sp_error: This will cache all SP and SF and open and lock all tables required for execution. */ - if (check_table_access(thd, SELECT_ACL, all_tables, 0) || + if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) || open_and_lock_tables(thd, all_tables)) goto error; @@ -4364,7 +4370,7 @@ create_sp_error: } case SQLCOM_DROP_VIEW: { - if (check_table_access(thd, DROP_ACL, all_tables, 0) || + if (check_table_access(thd, DROP_ACL, all_tables, UINT_MAX, FALSE) || end_active_trans(thd)) goto error; /* Conditionally writes to binlog. */ @@ -4840,7 +4846,7 @@ bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables) subselects_tables= subselects_tables->next_global; } if (subselects_tables && - (check_table_access(thd, SELECT_ACL, subselects_tables, 0))) + (check_table_access(thd, SELECT_ACL, subselects_tables, UINT_MAX, FALSE))) return 1; } return 0; @@ -5074,11 +5080,12 @@ static bool check_show_access(THD *thd, TABLE_LIST *table) /** Check the privilege for all used tables. - @param thd Thread context - @param want_access Privileges requested - @param tables List of tables to be checked - @param no_errors FALSE/TRUE - report/don't report error to - the client (using my_error() call). + @param thd Thread context + @param want_access Privileges requested + @param tables List of tables to be checked + @param number Check at most this number of tables. + @param no_errors FALSE/TRUE - report/don't report error to + the client (using my_error() call). @note Table privileges are cached in the table list for GRANT checking. @@ -5087,25 +5094,25 @@ static bool check_show_access(THD *thd, TABLE_LIST *table) (the latter should be either 0 or point to next_global member of one of elements of this table list). - @retval - FALSE OK - @retval - TRUE Access denied + @retval FALSE OK + @retval TRUE Access denied */ bool check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, - bool no_errors) + uint number, bool no_errors) { TABLE_LIST *org_tables= tables; TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table(); + uint i= 0; Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx; /* The check that first_not_own_table is not reached is for the case when the given table list refers to the list for prelocking (contains tables of other queries). For simple queries first_not_own_table is 0. */ - for (; tables != first_not_own_table; tables= tables->next_global) + for (; i < number && tables != first_not_own_table; + tables= tables->next_global, i++) { if (tables->security_ctx) sctx= tables->security_ctx; @@ -5155,7 +5162,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, } thd->security_ctx= backup_ctx; return check_grant(thd,want_access & ~EXTRA_ACL,org_tables, - test(want_access & EXTRA_ACL), UINT_MAX, no_errors); + test(want_access & EXTRA_ACL), number, no_errors); deny: thd->security_ctx= backup_ctx; return TRUE; @@ -6884,7 +6891,7 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables) /* sql_yacc guarantees that tables and aux_tables are not zero */ DBUG_ASSERT(aux_tables != 0); - if (check_table_access(thd, SELECT_ACL, tables, 0)) + if (check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) DBUG_RETURN(TRUE); /* @@ -6893,7 +6900,7 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables) call check_table_access() safely. */ thd->lex->query_tables_own_last= 0; - if (check_table_access(thd, DELETE_ACL, aux_tables, 0)) + if (check_table_access(thd, DELETE_ACL, aux_tables, UINT_MAX, FALSE)) { thd->lex->query_tables_own_last= save_query_tables_own_last; DBUG_RETURN(TRUE); @@ -7132,7 +7139,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, } } #endif - if (tables && check_table_access(thd, SELECT_ACL, tables,0)) + if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) goto err; } else if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 2a86844c8c6..5cd056807a6 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1619,7 +1619,7 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl bzero(&tables, sizeof(tables)); tables.db= (char *)"mysql"; tables.table_name= tables.alias= (char *)"plugin"; - if (check_table_access(thd, INSERT_ACL, &tables, 0)) + if (check_table_access(thd, INSERT_ACL, &tables, 1, FALSE)) DBUG_RETURN(TRUE); /* need to open before acquiring LOCK_plugin or it will deadlock */ diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index c0178a231c9..5a903a4fe1c 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1280,7 +1280,7 @@ static int mysql_test_select(Prepared_statement *stmt, ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL; if (tables) { - if (check_table_access(thd, privilege, tables,0)) + if (check_table_access(thd, privilege, tables, UINT_MAX, FALSE)) goto error; } else if (check_access(thd, privilege, any_db,0,0,0,0)) @@ -1349,7 +1349,7 @@ static bool mysql_test_do_fields(Prepared_statement *stmt, THD *thd= stmt->thd; DBUG_ENTER("mysql_test_do_fields"); - if (tables && check_table_access(thd, SELECT_ACL, tables, 0)) + if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) DBUG_RETURN(TRUE); if (open_normal_and_derived_tables(thd, tables, 0)) @@ -1380,7 +1380,7 @@ static bool mysql_test_set_fields(Prepared_statement *stmt, THD *thd= stmt->thd; set_var_base *var; - if (tables && check_table_access(thd, SELECT_ACL, tables, 0) || + if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE) || open_normal_and_derived_tables(thd, tables, 0)) goto error; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index ee0a6d3c2ab..6d817cb0620 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4059,7 +4059,7 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond) proc_tables.table_name= proc_tables.alias= (char*) "proc"; proc_tables.table_name_length= 4; proc_tables.lock_type= TL_READ; - full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, 1); + full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, 1, TRUE); if (!(proc_table= open_proc_table_for_read(thd, &open_tables_state_backup))) { DBUG_RETURN(1); @@ -4447,10 +4447,8 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables, Table_triggers_list *triggers= tables->table->triggers; int event, timing; -#ifndef NO_EMBEDDED_ACCESS_CHECKS - if (check_table_access(thd, TRIGGER_ACL, tables, 1)) + if (check_table_access(thd, TRIGGER_ACL, tables, 1, TRUE)) goto ret; -#endif for (event= 0; event < (int)TRG_EVENT_MAX; event++) { @@ -4488,9 +4486,7 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables, } } } -#ifndef NO_EMBEDDED_ACCESS_CHECKS ret: -#endif DBUG_RETURN(0); } diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 4bf23dc52f9..4cd1d542375 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -422,7 +422,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last; thd->lex->query_tables_own_last= 0; - err_status= check_table_access(thd, TRIGGER_ACL, tables, 0); + err_status= check_table_access(thd, TRIGGER_ACL, tables, 1, FALSE); thd->lex->query_tables_own_last= save_query_tables_own_last; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index da301b37484..1a4d7d515a8 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1123,8 +1123,8 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, if (!table->prelocking_placeholder && (old_lex->sql_command == SQLCOM_SELECT && old_lex->describe)) { - if (check_table_access(thd, SELECT_ACL, view_tables, 1) && - check_table_access(thd, SHOW_VIEW_ACL, table, 1)) + if (check_table_access(thd, SELECT_ACL, view_tables, UINT_MAX, TRUE) && + check_table_access(thd, SHOW_VIEW_ACL, table, UINT_MAX, TRUE)) { my_message(ER_VIEW_NO_EXPLAIN, ER(ER_VIEW_NO_EXPLAIN), MYF(0)); goto err; @@ -1134,7 +1134,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, (old_lex->sql_command == SQLCOM_SHOW_CREATE) && !table->belong_to_view) { - if (check_table_access(thd, SHOW_VIEW_ACL, table, 0)) + if (check_table_access(thd, SHOW_VIEW_ACL, table, UINT_MAX, FALSE)) goto err; } diff --git a/sql/stacktrace.c b/sql/stacktrace.c index b1267e20774..3d718dfd9d2 100644 --- a/sql/stacktrace.c +++ b/sql/stacktrace.c @@ -17,11 +17,16 @@ #include "stacktrace.h" #include #include +#include #ifdef HAVE_STACKTRACE #include #include +#if HAVE_EXECINFO_H +#include +#endif + #define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end) char *heap_start; @@ -93,9 +98,68 @@ inline uint32* find_prev_pc(uint32* pc, uchar** fp) } #endif /* defined(__alpha__) && defined(__GNUC__) */ +#if BACKTRACE_DEMANGLE +static void my_demangle_symbols(char **addrs, int n) +{ + int status, i; + char *begin, *end, *demangled; + + for (i= 0; i < n; i++) + { + demangled= NULL; + begin= strchr(addrs[i], '('); + end= begin ? strchr(begin, '+') : NULL; + + if (begin && end) + { + *begin++= *end++= '\0'; + demangled= my_demangle(begin, &status); + if (!demangled || status) + { + demangled= NULL; + begin[-1]= '('; + end[-1]= '+'; + } + } + + if (demangled) + fprintf(stderr, "%s(%s+%s\n", addrs[i], demangled, end); + else + fprintf(stderr, "%s\n", addrs[i]); + } +} +#endif + + +#if HAVE_BACKTRACE +static void backtrace_current_thread(void) +{ + void *addrs[128]; + char **strings= NULL; + int n = backtrace(addrs, array_elements(addrs)); +#if BACKTRACE_DEMANGLE + if ((strings= backtrace_symbols(addrs, n))) + { + my_demangle_symbols(strings, n); + free(strings); + } +#endif +#if HAVE_BACKTRACE_SYMBOLS_FD + if (!strings) + { + backtrace_symbols_fd(addrs, n, fileno(stderr)); + } +#endif +} +#endif + void print_stacktrace(uchar* stack_bottom, ulong thread_stack) { +#if HAVE_BACKTRACE + backtrace_current_thread(); + return; +#endif uchar** fp; uint frame_count = 0, sigreturn_frame_count; #if defined(__alpha__) && defined(__GNUC__) diff --git a/sql/stacktrace.h b/sql/stacktrace.h index 1a0b80c88d3..96c09a21ad6 100644 --- a/sql/stacktrace.h +++ b/sql/stacktrace.h @@ -17,6 +17,14 @@ extern "C" { #endif +#if HAVE_BACKTRACE && HAVE_BACKTRACE_SYMBOLS && HAVE_CXXABI_H && HAVE_ABI_CXA_DEMANGLE +#define BACKTRACE_DEMANGLE 1 +#endif + +#if BACKTRACE_DEMANGLE +char *my_demangle(const char *mangled_name, int *status); +#endif + #ifdef TARGET_OS_LINUX #if defined(HAVE_STACKTRACE) || (defined (__x86_64__) || defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) #undef HAVE_STACKTRACE