diff options
Diffstat (limited to 'client')
-rwxr-xr-x | client/CMakeLists.txt | 4 | ||||
-rw-r--r-- | client/Makefile.am | 18 | ||||
-rw-r--r-- | client/client_priv.h | 1 | ||||
-rw-r--r-- | client/get_password.c | 4 | ||||
-rw-r--r-- | client/my_readline.h | 2 | ||||
-rw-r--r-- | client/mysql.cc | 152 | ||||
-rw-r--r-- | client/mysql_upgrade.c | 83 | ||||
-rw-r--r-- | client/mysqladmin.cc | 6 | ||||
-rw-r--r-- | client/mysqlbinlog.cc | 8 | ||||
-rw-r--r-- | client/mysqlcheck.c | 58 | ||||
-rw-r--r-- | client/mysqldump.c | 20 | ||||
-rw-r--r-- | client/mysqlimport.c | 20 | ||||
-rw-r--r-- | client/mysqlshow.c | 4 | ||||
-rw-r--r-- | client/mysqlslap.c | 157 | ||||
-rw-r--r-- | client/mysqltest.cc | 614 | ||||
-rw-r--r-- | client/readline.cc | 7 | ||||
-rw-r--r-- | client/sql_string.cc | 7 | ||||
-rw-r--r-- | client/sql_string.h | 2 |
18 files changed, 721 insertions, 446 deletions
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index b4b633d007c..c04b4fc4b59 100755 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -19,8 +19,6 @@ INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake") # any of the clients here would go beyond the client API and access the # Thread Local Storage directly. -SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") -SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib @@ -84,3 +82,5 @@ IF(EMBED_MANIFESTS) MYSQL_EMBED_MANIFEST("echo" "asInvoker") ENDIF(EMBED_MANIFESTS) +INSTALL(TARGETS mysql mysqltest mysqlcheck mysqldump mysqlimport mysql_upgrade mysqlshow + mysqlbinlog mysqladmin mysqlslap echo DESTINATION bin COMPONENT runtime) diff --git a/client/Makefile.am b/client/Makefile.am index 1e7a9359462..a7104093e5f 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2011, Oracle and/or its affiliates # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -74,8 +74,7 @@ mysqlimport_SOURCES= mysqlimport.c mysqlimport_CFLAGS= -DTHREAD -UUNDEF_THREADS_HACK mysqlimport_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ @CLIENT_EXTRA_LDFLAGS@ \ - $(LIBMYSQLCLIENT_LA) \ - $(top_builddir)/mysys/libmysys.a + $(LIBMYSQLCLIENT_LA) mysqlshow_SOURCES= mysqlshow.c @@ -83,17 +82,15 @@ mysqlslap_SOURCES= mysqlslap.c mysqlslap_CFLAGS= -DTHREAD -UMYSQL_CLIENT_NO_THREADS mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ @CLIENT_EXTRA_LDFLAGS@ \ - $(LIBMYSQLCLIENT_LA) \ - $(top_builddir)/mysys/libmysys.a + $(LIBMYSQLCLIENT_LA) mysqltest_SOURCES= mysqltest.cc mysqltest_CXXFLAGS= -DTHREAD -UMYSQL_CLIENT_NO_THREADS mysqltest_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ @CLIENT_EXTRA_LDFLAGS@ \ - $(LIBMYSQLCLIENT_LA) \ $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/regex/libregex.a \ - $(CLIENT_THREAD_LIBS) + $(LIBMYSQLCLIENT_LA) \ + $(top_builddir)/regex/libregex.la mysql_upgrade_SOURCES= mysql_upgrade.c \ $(top_srcdir)/mysys/my_getpagesize.c @@ -108,7 +105,7 @@ sql_src=log_event.h mysql_priv.h rpl_constants.h \ log_event.cc my_decimal.h my_decimal.cc \ log_event_old.h log_event_old.cc \ rpl_record_old.h rpl_record_old.cc -strings_src=decimal.c +strings_src=decimal.c strings_def.h link_sources: for f in $(sql_src) ; do \ @@ -122,6 +119,3 @@ link_sources: rm -f my_user.c; \ @LN_CP_F@ $(top_srcdir)/sql-common/my_user.c my_user.c; echo timestamp > link_sources; - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/client/client_priv.h b/client/client_priv.h index ca3a7bc6d90..773d65c5d1e 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -92,6 +92,7 @@ enum options_client OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT, OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE, OPT_WRITE_BINLOG, OPT_DUMP_DATE, + OPT_ABORT_SOURCE_ON_ERROR, OPT_FIRST_SLAVE, OPT_ALL, OPT_MAX_CLIENT_OPTION diff --git a/client/get_password.c b/client/get_password.c index ea024f76fb6..c6653183f48 100644 --- a/client/get_password.c +++ b/client/get_password.c @@ -113,7 +113,7 @@ static void get_password(char *to,uint length,int fd, my_bool echo) for (;;) { - char tmp; + uchar tmp; if (my_read(fd,&tmp,1,MYF(0)) != 1) break; if (tmp == '\b' || (int) tmp == 127) @@ -138,7 +138,7 @@ static void get_password(char *to,uint length,int fd, my_bool echo) fputc('*',stderr); fflush(stderr); } - *(pos++) = tmp; + *(pos++)= (char) tmp; } while (pos != to && isspace(pos[-1]) == ' ') pos--; /* Allow dummy space at end */ diff --git a/client/my_readline.h b/client/my_readline.h index b556fa0cf83..30e59b613bc 100644 --- a/client/my_readline.h +++ b/client/my_readline.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2011, Oracle and/or its affiliates This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/client/mysql.cc b/client/mysql.cc index 3cb28e81164..385266d7c11 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1,5 +1,6 @@ /* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2009, 2012, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -12,8 +13,11 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#define COPYRIGHT_NOTICE "\ +This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ +and you are welcome to modify and redistribute it under the GPL v2 license\n" /* mysql command tool * Commands compatible with mSQL by David J. Hughes @@ -45,7 +49,7 @@ #include <locale.h> #endif -const char *VER= "14.14"; +const char *VER= "14.16"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 @@ -88,15 +92,15 @@ extern "C" { #include <term.h> #endif #endif -#endif +#endif /* defined(HAVE_CURSES_H) && defined(HAVE_TERM_H) */ +#undef bcmp // Fix problem with new readline #if defined(__WIN__) #include <conio.h> #elif !defined(__NETWARE__) #include <readline/readline.h> #define HAVE_READLINE #endif - //int vidattr(long unsigned int attrs); // Was missing in sun curses } #if !defined(HAVE_VIDATTR) @@ -150,9 +154,10 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0, default_pager_set= 0, opt_sigint_ignore= 0, show_warnings= 0, executing_query= 0, interrupted_query= 0, ignore_spaces= 0; -static my_bool debug_info_flag, debug_check_flag; +static my_bool debug_info_flag, debug_check_flag, batch_abort_on_error; static my_bool column_types_flag; static my_bool preserve_comments= 0; +static my_bool in_com_source, aborted= 0; static ulong opt_max_allowed_packet, opt_net_buffer_length; static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0; static uint my_end_arg; @@ -1029,7 +1034,7 @@ static const char *load_default_groups[]= { "mysql","client",0 }; static int embedded_server_arg_count= 0; static char *embedded_server_args[MAX_SERVER_ARGS]; static const char *embedded_server_groups[]= -{ "server", "embedded", "mysql_SERVER", 0 }; +{ "server", "embedded", "mysql_SERVER", "mariadb_SERVER", 0 }; #ifdef HAVE_READLINE /* @@ -1081,9 +1086,10 @@ int main(int argc,char *argv[]) delimiter_str= delimiter; default_prompt = my_strdup(getenv("MYSQL_PS1") ? getenv("MYSQL_PS1") : - "mysql> ",MYF(MY_WME)); + "\\N [\\d]> ",MYF(MY_WME)); current_prompt = my_strdup(default_prompt,MYF(MY_WME)); prompt_counter=0; + aborted= 0; outfile[0]=0; // no (default) outfile strmov(pager, "stdout"); // the default, if --pager wasn't given @@ -1163,10 +1169,11 @@ int main(int argc,char *argv[]) signal(SIGINT, handle_sigint); // Catch SIGINT to clean up signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up - put_info("Welcome to the MySQL monitor. Commands end with ; or \\g.", + put_info("Welcome to the MariaDB monitor. Commands end with ; or \\g.", INFO_INFO); sprintf((char*) glob_buffer.ptr(), - "Your MySQL connection id is %lu\nServer version: %s\n", + "Your %s connection id is %lu\nServer version: %s\n", + mysql_get_server_name(&mysql), mysql_thread_id(&mysql), server_version_string(&mysql)); put_info((char*) glob_buffer.ptr(),INFO_INFO); @@ -1279,15 +1286,16 @@ sig_handler mysql_end(int sig) /* This function handles sigint calls If query is in process, kill query + If 'source' is executed, abort source command no query in process, terminate like previous behavior */ + sig_handler handle_sigint(int sig) { char kill_buffer[40]; MYSQL *kill_mysql= NULL; /* terminate if no query being executed, or we already tried interrupting */ - /* terminate if no query being executed, or we already tried interrupting */ if (!executing_query || (interrupted_query == 2)) { tee_fprintf(stdout, "Ctrl-C -- exit!\n"); @@ -1302,6 +1310,7 @@ sig_handler handle_sigint(int sig) goto err; } + /* First time try to kill the query, second time the connection */ interrupted_query++; /* mysqld < 5 does not understand KILL QUERY, skip to KILL CONNECTION */ @@ -1312,11 +1321,15 @@ sig_handler handle_sigint(int sig) sprintf(kill_buffer, "KILL %s%lu", (interrupted_query == 1) ? "QUERY " : "", mysql_thread_id(&mysql)); - tee_fprintf(stdout, "Ctrl-C -- sending \"%s\" to server ...\n", kill_buffer); + if (verbose) + tee_fprintf(stdout, "Ctrl-C -- sending \"%s\" to server ...\n", + kill_buffer); mysql_real_query(kill_mysql, kill_buffer, (uint) strlen(kill_buffer)); mysql_close(kill_mysql); - tee_fprintf(stdout, "Ctrl-C -- query aborted.\n"); - + tee_fprintf(stdout, "Ctrl-C -- query killed. Continuing normally.\n"); + interrupted_query= 0; + if (in_com_source) + aborted= 1; // Abort source command return; err: @@ -1328,7 +1341,6 @@ err: handler called mysql_end(). */ mysql_thread_end(); - return; #else mysql_end(sig); #endif @@ -1341,6 +1353,10 @@ static struct my_option my_long_options[] = 0, 0, 0, 0, 0}, {"help", 'I', "Synonym for -?", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"abort-source-on-error", OPT_ABORT_SOURCE_ON_ERROR, + "Abort 'source filename' operations in case of errors", + &batch_abort_on_error, &batch_abort_on_error, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __NETWARE__ {"autoclose", OPT_AUTO_CLOSE, "Automatically close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -1396,7 +1412,7 @@ static struct my_option my_long_options[] = {"vertical", 'E', "Print the output of a query (rows) vertically.", &vertical, &vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"force", 'f', "Continue even if we get an SQL error.", + {"force", 'f', "Continue even if we get an SQL error. Sets abort-source-on-error to 0", &ignore_errors, &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"named-commands", 'G', @@ -1776,6 +1792,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), #endif break; #include <sslopt-case.h> + case 'f': + batch_abort_on_error= 0; + break; case 'V': usage(1); exit(0); @@ -1867,14 +1886,14 @@ static int read_and_execute(bool interactive) String buffer; #endif - char *line; + char *line= 0; char in_string=0; ulong line_number=0; bool ml_comment= 0; COMMANDS *com; status.exit_status=1; - - for (;;) + + while (!aborted) { if (!interactive) { @@ -2050,12 +2069,12 @@ static COMMANDS *find_command(char *name,char cmd_char) for (uint i= 0; commands[i].name; i++) { if (commands[i].func && - ((name && - !my_strnncoll(&my_charset_latin1, (uchar*)name, len, - (uchar*)commands[i].name,len) && - !commands[i].name[len] && - (!end || (end && commands[i].takes_params))) || - (!name && commands[i].cmd_char == cmd_char))) + (((name && + !my_strnncoll(&my_charset_latin1, (uchar*) name, len, + (uchar*) commands[i].name, len) && + !commands[i].name[len] && + (!end || (end && commands[i].takes_params)))) || + (!name && commands[i].cmd_char == cmd_char))) { DBUG_PRINT("exit",("found command: %s", commands[i].name)); DBUG_RETURN(&commands[i]); @@ -2213,16 +2232,21 @@ static bool add_line(String &buffer,char *line,char *in_string, } buffer.length(0); } - else if (!*ml_comment && (!*in_string && (inchar == '#' || - (inchar == '-' && pos[1] == '-' && - /* - The third byte is either whitespace or is the - end of the line -- which would occur only - because of the user sending newline -- which is - itself whitespace and should also match. - */ - (my_isspace(charset_info,pos[2]) || - !pos[2]))))) + else if (!*ml_comment && + (!*in_string && + (inchar == '#' || + (inchar == '-' && pos[1] == '-' && + /* + The third byte is either whitespace or is the end of + the line -- which would occur only because of the + user sending newline -- which is itself whitespace + and should also match. + We also ignore lines starting with '--', even if there + isn't a whitespace after. (This makes it easier to run + mysql-test-run cases through the client) + */ + ((my_isspace(charset_info,pos[2]) || !pos[2]) || + (buffer.is_empty() && out == line)))))) { // Flush previously accepted characters if (out != line) @@ -2919,13 +2943,8 @@ com_help(String *buffer __attribute__((unused)), return com_server_help(buffer,line,help_arg); } - put_info("\nFor information about MySQL products and services, visit:\n" - " http://www.mysql.com/\n" - "For developer information, including the MySQL Reference Manual, " - "visit:\n" - " http://dev.mysql.com/\n" - "To buy MySQL Enterprise support, training, or other products, visit:\n" - " https://shop.mysql.com/\n", INFO_INFO); + put_info("\nGeneral information about MariaDB can be found at\n" + "http://askmonty.org/wiki/index.php/Manual:Contents\n", INFO_INFO); put_info("List of all MySQL commands:", INFO_INFO); if (!named_cmds) put_info("Note that all text commands must be first on line and end with ';'",INFO_INFO); @@ -3866,8 +3885,9 @@ static int com_edit(String *buffer,char *line __attribute__((unused))) { char filename[FN_REFLEN],buff[160]; - int fd,tmp; + int fd,tmp,error; const char *editor; + MY_STAT stat_arg; if ((fd=create_temp_file(filename,NullS,"sql", O_CREAT | O_WRONLY, MYF(MY_WME))) < 0) @@ -3883,10 +3903,14 @@ com_edit(String *buffer,char *line __attribute__((unused))) !(editor = (char *)getenv("VISUAL"))) editor = "vi"; strxmov(buff,editor," ",filename,NullS); - if(system(buff) == -1) + if ((error= system(buff))) + { + char errmsg[100]; + sprintf(errmsg, "Command '%.40s' failed", buff); + put_info(errmsg, INFO_ERROR, 0, NullS); goto err; + } - MY_STAT stat_arg; if (!my_stat(filename,&stat_arg,MYF(MY_WME))) goto err; if ((fd = my_open(filename,O_RDONLY, MYF(MY_WME))) < 0) @@ -4030,6 +4054,7 @@ static int com_source(String *buffer __attribute__((unused)), int error; STATUS old_status; FILE *sql_file; + my_bool save_ignore_errors; /* Skip space from file name */ while (my_isspace(charset_info,*line)) @@ -4061,16 +4086,27 @@ static int com_source(String *buffer __attribute__((unused)), /* Save old status */ old_status=status; + save_ignore_errors= ignore_errors; bfill((char*) &status,sizeof(status),(char) 0); status.batch=old_status.batch; // Run in batch mode status.line_buff=line_buff; status.file_name=source_name; glob_buffer.length(0); // Empty command buffer + ignore_errors= !batch_abort_on_error; + in_com_source= 1; error= read_and_execute(false); + ignore_errors= save_ignore_errors; status=old_status; // Continue as before + in_com_source= aborted= 0; my_fclose(sql_file,MYF(0)); batch_readline_end(line_buff); + /* + If we got an error during source operation, don't abort the client + if ignore_errors is set + */ + if (error && ignore_errors) + error= -1; // Ignore error return error; } @@ -4417,6 +4453,7 @@ com_status(String *buffer __attribute__((unused)), tee_fprintf(stdout, "Using outfile:\t\t'%s'\n", opt_outfile ? outfile : ""); #endif tee_fprintf(stdout, "Using delimiter:\t%s\n", delimiter); + tee_fprintf(stdout, "Server:\t\t\t%s\n", mysql_get_server_name(&mysql)); tee_fprintf(stdout, "Server version:\t\t%s\n", server_version_string(&mysql)); tee_fprintf(stdout, "Protocol version:\t%d\n", mysql_get_proto_info(&mysql)); tee_fprintf(stdout, "Connection:\t\t%s\n", mysql_get_host_info(&mysql)); @@ -4585,12 +4622,19 @@ put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate) if (error) { if (sqlstate) - (void) tee_fprintf(file, "ERROR %d (%s): ", error, sqlstate); + (void) tee_fprintf(file, "ERROR %d (%s)", error, sqlstate); else - (void) tee_fprintf(file, "ERROR %d: ", error); + (void) tee_fprintf(file, "ERROR %d", error); } else - tee_puts("ERROR: ", file); + tee_fputs("ERROR", file); + if (status.query_start_line && line_numbers) + { + (void) fprintf(file," at line %lu",status.query_start_line); + if (status.file_name) + (void) fprintf(file," in file: '%s'", status.file_name); + } + tee_fputs(": ", file); } else vidattr(A_BOLD); @@ -4599,7 +4643,7 @@ put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate) } if (unbuffered) fflush(file); - return info_type == INFO_ERROR ? -1 : 0; + return info_type == INFO_ERROR ? (ignore_errors ? -1 : 1): 0; } @@ -4739,7 +4783,7 @@ static void mysql_end_timer(ulong start_time,char *buff) strmov(strend(buff),")"); } -static const char* construct_prompt() +static const char *construct_prompt() { processed_prompt.free(); // Erase the old prompt time_t lclock = time(NULL); // Get the date struct @@ -4768,6 +4812,12 @@ static const char* construct_prompt() case 'd': processed_prompt.append(current_db ? current_db : "(none)"); break; + case 'N': + if (connected) + processed_prompt.append(mysql_get_server_name(&mysql)); + else + processed_prompt.append("unknown"); + break; case 'h': { const char *prompt; diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 2512f5269ab..b7d7565edae 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2006, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,7 +21,7 @@ #include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ -#define VER "1.1" +#define VER "1.2" #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> @@ -38,8 +38,9 @@ static char mysql_path[FN_REFLEN]; static char mysqlcheck_path[FN_REFLEN]; -static my_bool opt_force, opt_verbose, debug_info_flag, debug_check_flag; -static uint my_end_arg= 0; +static my_bool opt_force, debug_info_flag, debug_check_flag, opt_silent; +static my_bool opt_not_used; /* For compatiblity */ +static uint my_end_arg= 0, opt_verbose; static char *opt_user= (char*)"root"; static DYNAMIC_STRING ds_args; @@ -66,12 +67,14 @@ static struct my_option my_long_options[]= { {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"basedir", 'b', "Not used by mysql_upgrade. Only for backward compatibility.", + {"basedir", 'b', + "Not used by mysql_upgrade. Only for backward compatibility.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"character-sets-dir", OPT_CHARSETS_DIR, - "Directory for character set files.", 0, - 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"compress", OPT_COMPRESS, "Use compression in server/client protocol.", + "Not used by mysql_upgrade. Only for backward compatibility.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + {"compress", OPT_COMPRESS, + "Not used by mysql_upgrade. Only for backward compatibility.", ¬_used, ¬_used, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"datadir", 'd', "Not used by mysql_upgrade. Only for backward compatibility.", @@ -84,18 +87,17 @@ static struct my_option my_long_options[]= &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.", - &debug_check_flag, &debug_check_flag, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + &debug_check_flag, &debug_check_flag, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"debug-info", 'T', "Print some debug info at exit.", &debug_info_flag, &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"default-character-set", OPT_DEFAULT_CHARSET, - "Set the default character set.", 0, - 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + "Not used by mysql_upgrade. Only for backward compatibility.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"force", 'f', "Force execution of mysqlcheck even if mysql_upgrade " "has already been executed for the current version of MySQL.", - &opt_force, &opt_force, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"host",'h', "Connect to host.", 0, + &opt_force, &opt_force, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"host", 'h', "Connect to host.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"password", 'p', "Password to use when connecting to server. If password is not given," @@ -120,6 +122,8 @@ static struct my_option my_long_options[]= "Base name of shared memory.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif + {"silent", 's', "Print less information", &opt_silent, + &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"socket", 'S', "The socket file to use for connection.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #include <sslopt-longopts.h> @@ -128,8 +132,7 @@ static struct my_option my_long_options[]= {"user", 'u', "User for login if not current user.", &opt_user, &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"verbose", 'v', "Display more output about the process.", - &opt_verbose, &opt_verbose, 0, - GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + &opt_not_used, &opt_not_used, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"write-binlog", OPT_WRITE_BINLOG, "All commands including mysqlcheck are binlogged. Enabled by default;" "use --skip-write-binlog when commands should not be sent to replication slaves.", @@ -177,7 +180,7 @@ static void verbose(const char *fmt, ...) { va_list args; - if (!opt_verbose) + if (opt_silent) return; /* Print the verbose message */ @@ -230,9 +233,9 @@ get_one_option(int optid, const struct my_option *opt, switch (optid) { case '?': - puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); puts("MySQL utility for upgrading databases to new MySQL versions.\n"); my_print_help(my_long_options); exit(0); @@ -271,6 +274,18 @@ get_one_option(int optid, const struct my_option *opt, /* FALLTHROUGH */ case 'v': /* --verbose */ + opt_verbose++; + if (argument == disabled_my_option) + { + opt_verbose= 0; + opt_silent= 1; + } + add_option= 0; + break; + case 's': + opt_verbose= 0; + add_option= 0; + break; case 'f': /* --force */ add_option= FALSE; break; @@ -431,7 +446,8 @@ static void find_tool(char *tool_executable_name, const char *tool_name, len, self_name, FN_LIBCHAR, tool_name); } - verbose("Looking for '%s' as: %s", tool_name, tool_executable_name); + if (opt_verbose) + verbose("Looking for '%s' as: %s", tool_name, tool_executable_name); /* Make sure it can be executed @@ -501,7 +517,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res, "--database=mysql", "--batch", /* Turns off pager etc. */ force ? "--force": "--skip-force", - ds_res ? "--silent": "", + ds_res || opt_silent ? "--silent": "", "<", query_file_path, "2>&1", @@ -583,7 +599,6 @@ static int upgrade_already_done(void) FILE *in; char upgrade_info_file[FN_REFLEN]= {0}; char buf[sizeof(MYSQL_SERVER_VERSION)+1]; - char *res; if (get_upgrade_info_file_name(upgrade_info_file)) return 0; /* Could not get filename => not sure */ @@ -591,19 +606,15 @@ static int upgrade_already_done(void) if (!(in= my_fopen(upgrade_info_file, O_RDONLY, MYF(0)))) return 0; /* Could not open file => not sure */ - /* - Read from file, don't care if it fails since it - will be detected by the strncmp - */ bzero(buf, sizeof(buf)); - res= fgets(buf, sizeof(buf), in); + if (!fgets(buf, sizeof(buf), in)) + { + /* Ignore, will be detected by strncmp() below */ + } my_fclose(in, MYF(0)); - if (!res) - return 0; /* Could not read from file => not sure */ - - return (strncmp(res, MYSQL_SERVER_VERSION, + return (strncmp(buf, MYSQL_SERVER_VERSION, sizeof(MYSQL_SERVER_VERSION)-1)==0); } @@ -659,6 +670,8 @@ static void create_mysql_upgrade_info_file(void) static void print_conn_args(const char *tool_name) { + if (opt_verbose < 2) + return; if (conn_args.str[0]) verbose("Running '%s' with connection arguments: %s", tool_name, conn_args.str); @@ -674,6 +687,7 @@ static void print_conn_args(const char *tool_name) static int run_mysqlcheck_upgrade(void) { + verbose("Phase 2/3: Checking and upgrading tables"); print_conn_args("mysqlcheck"); return run_tool(mysqlcheck_path, NULL, /* Send output from mysqlcheck directly to screen */ @@ -682,6 +696,8 @@ static int run_mysqlcheck_upgrade(void) "--check-upgrade", "--all-databases", "--auto-repair", + !opt_silent || opt_verbose ? "--verbose": "", + opt_silent ? "--silent": "", opt_write_binlog ? "--write-binlog" : "--skip-write-binlog", NULL); } @@ -689,6 +705,7 @@ static int run_mysqlcheck_upgrade(void) static int run_mysqlcheck_fixnames(void) { + verbose("Phase 1/3: Fixing table and database names"); print_conn_args("mysqlcheck"); return run_tool(mysqlcheck_path, NULL, /* Send output from mysqlcheck directly to screen */ @@ -697,6 +714,8 @@ static int run_mysqlcheck_fixnames(void) "--all-databases", "--fix-db-names", "--fix-table-names", + opt_verbose ? "--verbose": "", + opt_silent ? "--silent": "", opt_write_binlog ? "--write-binlog" : "--skip-write-binlog", NULL); } @@ -766,7 +785,7 @@ static int run_sql_fix_privilege_tables(void) if (init_dynamic_string(&ds_result, "", 512, 512)) die("Out of memory"); - verbose("Running 'mysql_fix_privilege_tables'..."); + verbose("Phase 3/3: Running 'mysql_fix_privilege_tables'..."); run_query(mysql_fix_privilege_tables, &ds_result, /* Collect result */ TRUE); diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index d5d6ad9ff6a..36de80b6f6e 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -594,7 +594,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) If this behaviour is ever changed, Docs should be notified. */ - struct rand_struct rand_st; + struct my_rnd_struct rand_st; for (; argc > 0 ; argv++,argc--) { @@ -913,7 +913,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) time_t start_time; /* Do initialization the same way as we do in mysqld */ start_time=time((time_t*) 0); - randominit(&rand_st,(ulong) start_time,(ulong) start_time/2); + my_rnd_init(&rand_st,(ulong) start_time,(ulong) start_time/2); if (argc < 2) { diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index c32f92ae149..8ac00052f97 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -441,7 +441,7 @@ Exit_status Load_log_processor::process_first_event(const char *bname, ptr= fname + target_dir_name_len; memcpy(ptr,bname,blen); ptr+= blen; - ptr+= sprintf(ptr, "-%x", file_id); + ptr+= my_sprintf(ptr, (ptr, "-%x", file_id)); if ((file= create_unique_file(fname,ptr)) < 0) { @@ -1416,6 +1416,10 @@ static int parse_args(int *argc, char*** argv) */ static Exit_status safe_connect() { + /* Close and old connections to MySQL */ + if (mysql) + mysql_close(mysql); + mysql= mysql_init(NULL); if (!mysql) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index ec9ee50868b..038fc21b66e 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2001, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#define CHECK_VERSION "2.5.0" +#define CHECK_VERSION "2.6.0" #include "client_priv.h" #include <m_ctype.h> @@ -72,8 +72,8 @@ static struct my_option my_long_options[] = &opt_auto_repair, &opt_auto_repair, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"character-sets-dir", OPT_CHARSETS_DIR, - "Directory for character set files.", &charsets_dir, - &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + "Directory for character set files.", (char**) &charsets_dir, + (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"check", 'c', "Check table for errors.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"check-only-changed", 'C', @@ -226,19 +226,17 @@ static void usage(void) puts("This program can be used to CHECK (-c, -m, -C), REPAIR (-r), ANALYZE (-a),"); puts("or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be"); puts("used at the same time. Not all options are supported by all storage engines."); - puts("Please consult the MySQL manual for latest information about the"); - puts("above. The options -c, -r, -a, and -o are exclusive to each other, which"); + puts("The options -c, -r, -a, and -o are exclusive to each other, which"); puts("means that the last option will be used, if several was specified.\n"); - puts("The option -c will be used by default, if none was specified. You"); - puts("can change the default behavior by making a symbolic link, or"); + puts("The option -c (--check) will be used by default, if none was specified."); + puts("You can change the default behavior by making a symbolic link, or"); puts("copying this file somewhere with another name, the alternatives are:"); puts("mysqlrepair: The default option will be -r"); puts("mysqlanalyze: The default option will be -a"); puts("mysqloptimize: The default option will be -o\n"); - printf("Usage: %s [OPTIONS] database [tables]\n", my_progname); - printf("OR %s [OPTIONS] --databases DB1 [DB2 DB3...]\n", - my_progname); - printf("OR %s [OPTIONS] --all-databases\n", my_progname); + puts("Please consult the MariaDB/MySQL knowledgebase at"); + puts("http://kb.askmonty.org/v/mysqlcheck for latest information about"); + puts("this program."); print_defaults("my", load_default_groups); my_print_help(my_long_options); my_print_variables(my_long_options); @@ -415,6 +413,8 @@ static int process_all_databases() MYF(0), mysql_error(sock)); return 1; } + if (verbose) + printf("Processing databases\n"); while ((row = mysql_fetch_row(tableres))) { if (process_one_db(row[0])) @@ -428,6 +428,8 @@ static int process_all_databases() static int process_databases(char **db_names) { int result = 0; + if (verbose) + printf("Processing databases\n"); for ( ; *db_names ; db_names++) { if (process_one_db(*db_names)) @@ -520,6 +522,7 @@ static int process_all_tables_in_db(char *database) MYSQL_RES *res; MYSQL_ROW row; uint num_columns; + my_bool system_database= 0; LINT_INIT(res); if (use_db(database)) @@ -533,6 +536,9 @@ static int process_all_tables_in_db(char *database) return 1; } + if (!strcmp(database, "mysql") || !strcmp(database, "MYSQL")) + system_database= 1; + num_columns= mysql_num_fields(res); if (opt_all_in_1 && what_to_do != DO_UPGRADE) @@ -575,6 +581,10 @@ static int process_all_tables_in_db(char *database) /* Skip views if we don't perform renaming. */ if ((what_to_do != DO_UPGRADE) && (num_columns == 2) && (strcmp(row[1], "VIEW") == 0)) continue; + if (system_database && + (!strcmp(row[0], "general_log") || + !strcmp(row[0], "slow_log"))) + continue; /* Skip logging tables */ handle_request_for_tables(row[0], fixed_name_length(row[0])); } @@ -623,6 +633,8 @@ static int fix_database_storage_name(const char *name) static int process_one_db(char *database) { + if (verbose) + puts(database); if (what_to_do == DO_UPGRADE) { int rc= 0; @@ -702,7 +714,8 @@ static int handle_request_for_tables(char *tables, uint length) if (opt_all_in_1) { /* No backticks here as we added them before */ - query_length= sprintf(query, "%s TABLE %s %s", op, tables, options); + query_length= my_sprintf(query, + (query, "%s TABLE %s %s", op, tables, options)); } else { @@ -729,7 +742,7 @@ static void print_result() { MYSQL_RES *res; MYSQL_ROW row; - char prev[NAME_LEN*2+2]; + char prev[(NAME_LEN+9)*2+2]; uint i; my_bool found_error=0; @@ -759,7 +772,15 @@ static void print_result() printf("%-50s %s", row[0], row[3]); else if (!status && changed) { - printf("%s\n%-9s: %s", row[0], row[2], row[3]); + /* + If the error message includes REPAIR TABLE, we assume it means + we have to run upgrade on it. In this case we write a nicer message + than "Please do "REPAIR TABLE""... + */ + if (!strcmp(row[2],"error") && strinstr(row[3],"REPAIR TABLE") != 0) + printf("%-50s %s", row[0], "Needs upgrade"); + else + printf("%s\n%-9s: %s", row[0], row[2], row[3]); if (strcmp(row[2],"note")) found_error=1; } @@ -778,7 +799,7 @@ static void print_result() static int dbConnect(char *host, char *user, char *passwd) { DBUG_ENTER("dbConnect"); - if (verbose) + if (verbose > 1) { fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost"); } @@ -811,7 +832,7 @@ static int dbConnect(char *host, char *user, char *passwd) static void dbDisconnect(char *host) { - if (verbose) + if (verbose > 1) fprintf(stderr, "# Disconnecting from %s...\n", host ? host : "localhost"); mysql_close(sock); } /* dbDisconnect */ @@ -855,7 +876,8 @@ int main(int argc, char **argv) if (!opt_write_binlog) { - if (disable_binlog()) { + if (disable_binlog()) + { first_error= 1; goto end; } diff --git a/client/mysqldump.c b/client/mysqldump.c index 3fda1fafc24..b271cb8429b 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -227,8 +227,8 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"character-sets-dir", OPT_CHARSETS_DIR, - "Directory for character set files.", &charsets_dir, - &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + "Directory for character set files.", (char**) &charsets_dir, + (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"comments", 'i', "Write additional information.", &opt_comments, &opt_comments, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -258,8 +258,8 @@ static struct my_option my_long_options[] = {"debug", '#', "This is a non-debug version. Catch this and exit.", 0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0}, #else - {"debug", '#', "Output debug log.", &default_dbug_option, - &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"debug", '#', "Output debug log.", (char**) &default_dbug_option, + (char**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.", &debug_check_flag, &debug_check_flag, 0, @@ -983,7 +983,7 @@ static int get_options(int *argc, char ***argv) static void DB_error(MYSQL *mysql_arg, const char *when) { DBUG_ENTER("DB_error"); - maybe_die(EX_MYSQLERR, "Got error: %d: %s %s", + maybe_die(EX_MYSQLERR, "Got error: %d: \"%s\" %s", mysql_errno(mysql_arg), mysql_error(mysql_arg), when); DBUG_VOID_RETURN; } @@ -1466,6 +1466,7 @@ static void free_resources() if (md_result_file && md_result_file != stdout) my_fclose(md_result_file, MYF(0)); my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR)); + my_free(current_host, MYF(MY_ALLOW_ZERO_PTR)); if (hash_inited(&ignore_table)) hash_free(&ignore_table); if (extended_insert) @@ -4486,7 +4487,7 @@ static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root) } mysql_free_result(table_res); } - DBUG_PRINT("exit", ("new_table_name: %s", name)); + DBUG_PRINT("exit", ("new_table_name: %s", val_or_null(name))); DBUG_RETURN(name); } @@ -5079,6 +5080,7 @@ static my_bool get_view_structure(char *table, char* db) field= mysql_fetch_field_direct(table_res, 0); if (strcmp(field->name, "View") != 0) { + mysql_free_result(table_res); switch_character_set_results(mysql, default_charset); verbose_msg("-- It's base table, skipped\n"); DBUG_RETURN(0); @@ -5088,8 +5090,10 @@ static my_bool get_view_structure(char *table, char* db) if (path) { if (!(sql_file= open_sql_file_for_table(table, O_WRONLY))) + { + mysql_free_result(table_res); DBUG_RETURN(1); - + } write_header(sql_file, db); } diff --git a/client/mysqlimport.c b/client/mysqlimport.c index a739c5aded0..45ee643691b 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,8 +18,14 @@ /* ** mysqlimport.c - Imports all given files ** into a table(s). +** +** ************************* +** * * +** * AUTHOR: Monty & Jani * +** * DATE: June 24, 1997 * +** * * +** ************************* */ - #define IMPORT_VERSION "3.7" #include "client_priv.h" @@ -28,6 +34,8 @@ #include <my_pthread.h> #endif +#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ + /* Global Thread counter */ uint counter; @@ -36,8 +44,6 @@ pthread_mutex_t counter_mutex; pthread_cond_t count_threshhold; #endif -#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ - static void db_error_with_table(MYSQL *mysql, char *table); static void db_error(MYSQL *mysql); static char *field_escape(char *to,const char *from,uint length); @@ -71,8 +77,8 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"character-sets-dir", OPT_CHARSETS_DIR, - "Directory for character set files.", &charsets_dir, - &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + "Directory for character set files.", (char**) &charsets_dir, + (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default-character-set", OPT_DEFAULT_CHARSET, "Set the default character set.", &default_charset, &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -195,6 +201,8 @@ static void print_version(void) static void usage(void) { + puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); + puts("Copyright 2008-2011 Oracle and Monty Program Ab."); print_version(); puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); printf("\ diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 1656ec71af8..8b3628289d3 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -167,7 +167,7 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"character-sets-dir", 'c', "Directory for character set files.", - &charsets_dir, &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, + (char**) &charsets_dir, (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default-character-set", OPT_DEFAULT_CHARSET, "Set the default character set.", &default_charset, diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 4c4dbafc24d..98ca775bee5 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2005, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -295,6 +295,25 @@ static int gettimeofday(struct timeval *tp, void *tzp) } #endif +void set_mysql_connect_options(MYSQL *mysql) +{ + if (opt_compress) + mysql_options(mysql,MYSQL_OPT_COMPRESS,NullS); +#ifdef HAVE_OPENSSL + if (opt_use_ssl) + mysql_ssl_set(mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, + opt_ssl_capath, opt_ssl_cipher); +#endif + if (opt_protocol) + mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); +#ifdef HAVE_SMEM + if (shared_memory_base_name) + mysql_options(mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); +#endif + mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset); +} + + int main(int argc, char **argv) { MYSQL mysql; @@ -326,20 +345,7 @@ int main(int argc, char **argv) exit(1); } mysql_init(&mysql); - if (opt_compress) - mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS); -#ifdef HAVE_OPENSSL - if (opt_use_ssl) - mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, - opt_ssl_capath, opt_ssl_cipher); -#endif - if (opt_protocol) - mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); -#ifdef HAVE_SMEM - if (shared_memory_base_name) - mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); -#endif - mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset); + set_mysql_connect_options(&mysql); if (!opt_only_print) { @@ -452,7 +458,16 @@ void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr) /* First we create */ if (create_statements) + { + /* + If we have an --engine option, then we indicate + create_schema() to add the engine type to the DDL. + */ + if (eptr) + create_statements->type= CREATE_TABLE_TYPE; + create_schema(mysql, create_schema_string, create_statements, eptr); + } /* If we generated GUID we need to build a list of them from creation that @@ -466,10 +481,10 @@ void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr) if (commit_rate) run_query(mysql, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0")); - if (pre_system) - if ((sysret= system(pre_system)) != 0) - fprintf(stderr, "Warning: Execution of pre_system option returned %d.\n", - sysret); + if (pre_system && (sysret= system(pre_system)) != 0) + fprintf(stderr, + "Warning: Execution of pre_system option returned %d.\n", + sysret); /* Pre statements are always run after all other logic so they can @@ -483,11 +498,10 @@ void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr) if (post_statements) run_statements(mysql, post_statements); - if (post_system) - if ((sysret= system(post_system)) != 0) - fprintf(stderr, "Warning: Execution of post_system option returned %d.\n", - sysret); - + if (post_system && (sysret= system(post_system)) != 0) + fprintf(stderr, + "Warning: Execution of post_system option returned %d.\n", + sysret); /* We are finished with this run */ if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary) drop_primary_key_list(); @@ -532,7 +546,7 @@ static struct my_option my_long_options[] = 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"auto-generate-sql-load-type", OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE, "Specify test load type: mixed, update, write, key, or read; default is mixed.", - &auto_generate_sql_type, &auto_generate_sql_type, + (char**) &auto_generate_sql_type, (char**) &auto_generate_sql_type, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"auto-generate-sql-secondary-indexes", OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES, @@ -563,13 +577,13 @@ static struct my_option my_long_options[] = &opt_compress, &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"concurrency", 'c', "Number of clients to simulate for query to run.", - &concurrency_str, &concurrency_str, 0, GET_STR, + (char**) &concurrency_str, (char**) &concurrency_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"create", OPT_SLAP_CREATE_STRING, "File or string to use create tables.", &create_string, &create_string, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"create-schema", OPT_CREATE_SLAP_SCHEMA, "Schema to run tests in.", - &create_schema_string, &create_schema_string, 0, GET_STR, + (char**) &create_schema_string, (char**) &create_schema_string, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"csv", OPT_SLAP_CSV, "Generate CSV output to named file or to stdout if no file is named.", @@ -579,7 +593,7 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0}, #else {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", - &default_dbug_option, &default_dbug_option, 0, GET_STR, + (char**) &default_dbug_option, (char**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.", @@ -589,14 +603,17 @@ static struct my_option my_long_options[] = &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"delimiter", 'F', "Delimiter to use in SQL statements supplied in file or command line.", - &delimiter, &delimiter, 0, GET_STR, REQUIRED_ARG, + (char**) &delimiter, (char**) &delimiter, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"detach", OPT_SLAP_DETACH, "Detach (close and reopen) connections after X number of requests.", &detach_rate, &detach_rate, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"engine", 'e', "Storage engine to use for creating the table.", - &default_engine, &default_engine, 0, + {"engine", 'e', + "Comma separated list of storage engines to use for creating the table." + " The test is run for each engine. You can also specify an option for an " + "engine after a `:', like memory:max_row=2300", + &default_engine, &default_engine, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", &host, &host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -606,11 +623,11 @@ static struct my_option my_long_options[] = &opt_no_drop, &opt_no_drop, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"number-char-cols", 'x', "Number of VARCHAR columns to create in table if specifying --auto-generate-sql.", - &num_char_cols_opt, &num_char_cols_opt, 0, GET_STR, REQUIRED_ARG, + (char**) &num_char_cols_opt, (char**) &num_char_cols_opt, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"number-int-cols", 'y', "Number of INT columns to create in table if specifying --auto-generate-sql.", - &num_int_cols_opt, &num_int_cols_opt, 0, GET_STR, REQUIRED_ARG, + (char**) &num_int_cols_opt, (char**) &num_int_cols_opt, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"number-of-queries", OPT_MYSQL_NUMBER_OF_QUERY, "Limit each client to this number of queries (this is not exact).", @@ -969,6 +986,7 @@ build_update_string(void) ptr->type= UPDATE_TYPE_REQUIRES_PREFIX ; else ptr->type= UPDATE_TYPE; + strmov(ptr->string, update_string.str); dynstr_free(&update_string); DBUG_RETURN(ptr); @@ -984,8 +1002,8 @@ build_update_string(void) static statement * build_insert_string(void) { - char buf[HUGE_STRING_LENGTH]; - unsigned int col_count; + char buf[HUGE_STRING_LENGTH]; + unsigned int col_count; statement *ptr; DYNAMIC_STRING insert_string; DBUG_ENTER("build_insert_string"); @@ -1075,8 +1093,8 @@ build_insert_string(void) static statement * build_select_string(my_bool key) { - char buf[HUGE_STRING_LENGTH]; - unsigned int col_count; + char buf[HUGE_STRING_LENGTH]; + unsigned int col_count; statement *ptr; static DYNAMIC_STRING query_string; DBUG_ENTER("build_select_string"); @@ -1128,6 +1146,7 @@ build_select_string(my_bool key) ptr->type= SELECT_TYPE_REQUIRES_PREFIX; else ptr->type= SELECT_TYPE; + strmov(ptr->string, query_string.str); dynstr_free(&query_string); DBUG_RETURN(ptr); @@ -1189,8 +1208,6 @@ get_options(int *argc,char ***argv) exit(1); } - - if (auto_generate_sql && num_of_query && auto_actual_queries) { fprintf(stderr, @@ -1231,6 +1248,7 @@ get_options(int *argc,char ***argv) num_int_cols= atoi(str->string); if (str->option) num_int_cols_index= atoi(str->option); + option_cleanup(str); } @@ -1243,6 +1261,7 @@ get_options(int *argc,char ***argv) num_char_cols_index= atoi(str->option); else num_char_cols_index= 0; + option_cleanup(str); } @@ -1477,6 +1496,7 @@ get_options(int *argc,char ***argv) if (tty_password) opt_password= get_tty_password(NullS); + DBUG_RETURN(0); } @@ -1491,6 +1511,7 @@ static int run_query(MYSQL *mysql, const char *query, int len) if (verbose >= 3) printf("%.*s;\n", len, query); + return mysql_real_query(mysql, query, len); } @@ -1611,18 +1632,6 @@ create_schema(MYSQL *mysql, const char *db, statement *stmt, } } - if (engine_stmt) - { - len= snprintf(query, HUGE_STRING_LENGTH, "set storage_engine=`%s`", - engine_stmt->string); - if (run_query(mysql, query, len)) - { - fprintf(stderr,"%s: Cannot set default engine: %s\n", my_progname, - mysql_error(mysql)); - exit(1); - } - } - count= 0; after_create= stmt; @@ -1636,8 +1645,21 @@ limit_not_met: { char buffer[HUGE_STRING_LENGTH]; - snprintf(buffer, HUGE_STRING_LENGTH, "%s %s", ptr->string, - engine_stmt->option); + snprintf(buffer, HUGE_STRING_LENGTH, "%s Engine = %s %s", + ptr->string, engine_stmt->string, engine_stmt->option); + if (run_query(mysql, buffer, strlen(buffer))) + { + fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n", + my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql)); + exit(1); + } + } + else if (engine_stmt && engine_stmt->string && ptr->type == CREATE_TABLE_TYPE) + { + char buffer[HUGE_STRING_LENGTH]; + + snprintf(buffer, HUGE_STRING_LENGTH, "%s Engine = %s", + ptr->string, engine_stmt->string); if (run_query(mysql, buffer, strlen(buffer))) { fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n", @@ -1671,6 +1693,7 @@ drop_schema(MYSQL *mysql, const char *db) { char query[HUGE_STRING_LENGTH]; int len; + DBUG_ENTER("drop_schema"); len= snprintf(query, HUGE_STRING_LENGTH, "DROP SCHEMA IF EXISTS `%s`", db); @@ -1807,6 +1830,7 @@ pthread_handler_t run_task(void *p) my_progname, mysql_error(mysql)); exit(0); } + set_mysql_connect_options(mysql); if (mysql_thread_init()) { @@ -1847,7 +1871,6 @@ limit_not_met: my_progname, mysql_error(mysql)); exit(0); } - if (slap_connect(mysql)) goto end; } @@ -1957,17 +1980,27 @@ parse_option(const char *origin, option_string **stmt, char delm) uint count= 0; /* We know that there is always one */ for (tmp= *sptr= (option_string *)my_malloc(sizeof(option_string), - MYF(MY_ZEROFILL|MY_FAE|MY_WME)); + MYF(MY_ZEROFILL|MY_FAE|MY_WME)); (retstr= strchr(ptr, delm)); tmp->next= (option_string *)my_malloc(sizeof(option_string), - MYF(MY_ZEROFILL|MY_FAE|MY_WME)), + MYF(MY_ZEROFILL|MY_FAE|MY_WME)), tmp= tmp->next) { - char buffer[HUGE_STRING_LENGTH]; + /* + Initialize buffer, because otherwise an + --engine=<storage_engine>:<option>,<eng1>,<eng2> + will crash. + */ + char buffer[HUGE_STRING_LENGTH]= ""; char *buffer_ptr; count++; strncpy(buffer, ptr, (size_t)(retstr - ptr)); + /* + Handle --engine=memory:max_row=200 cases, or more general speaking + --engine=<storage_engine>:<options>, which will be translated to + Engine = storage_engine option. + */ if ((buffer_ptr= strchr(buffer, ':'))) { char *option_ptr; @@ -1988,13 +2021,15 @@ parse_option(const char *origin, option_string **stmt, char delm) tmp->length= (size_t)(retstr - ptr); } + /* Skip delimiter delm */ ptr+= retstr - ptr + 1; if (isspace(*ptr)) ptr++; + count++; } - if (ptr != origin+length) + if (ptr != origin + length) { char *origin_ptr; @@ -2003,7 +2038,7 @@ parse_option(const char *origin, option_string **stmt, char delm) char *option_ptr; tmp->length= (size_t)(origin_ptr - ptr); - tmp->string= my_strndup(origin, tmp->length, MYF(MY_FAE)); + tmp->string= my_strndup(ptr, tmp->length, MYF(MY_FAE)); option_ptr= (char *)ptr + 1 + tmp->length; @@ -2053,7 +2088,7 @@ parse_delimiter(const char *script, statement **stmt, char delm) if (ptr != script+length) { tmp->string= my_strndup(ptr, (uint)((script + length) - ptr), - MYF(MY_FAE)); + MYF(MY_FAE)); tmp->length= (size_t)((script + length) - ptr); count++; } @@ -2111,6 +2146,7 @@ print_conclusions_csv(conclusions *con) { char buffer[HUGE_STRING_LENGTH]; const char *ptr= auto_generate_sql_type ? auto_generate_sql_type : "query"; + snprintf(buffer, HUGE_STRING_LENGTH, "%s,%s,%ld.%03ld,%ld.%03ld,%ld.%03ld,%d,%llu\n", con->engine ? con->engine : "", /* Storage engine we ran against */ @@ -2200,6 +2236,7 @@ slap_connect(MYSQL *mysql) int x, connect_error= 1; for (x= 0; x < 10; x++) { + set_mysql_connect_options(mysql); if (mysql_real_connect(mysql, host, user, opt_password, create_schema_string, opt_mysql_port, diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 89fcb56825e..9a29e5e040c 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1,5 +1,5 @@ -/* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2009, 2012 Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,6 +24,14 @@ http://dev.mysql.com/doc/mysqltest/en/index.html Please keep the test framework tools identical in all versions! + + Written by: + Sasha Pachev <sasha@mysql.com> + Matt Wagner <matt@mysql.com> + Monty + Jani + Holyfoot + And many others */ #define MTEST_VERSION "3.3" @@ -64,7 +72,7 @@ #define MAX_COLUMNS 256 #define MAX_EMBEDDED_SERVER_ARGS 64 #define MAX_DELIMITER_LENGTH 16 -#define DEFAULT_MAX_CONN 128 +#define DEFAULT_MAX_CONN 64 /* Flags controlling send and reap */ #define QUERY_SEND_FLAG 1 @@ -78,7 +86,8 @@ enum { OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION, OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL, OPT_MAX_CONNECT_RETRIES, OPT_MAX_CONNECTIONS, - OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES + OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES, + OPT_GLOBAL_SUBST, OPT_MY_CONNECT_TIMEOUT }; static int record= 0, opt_sleep= -1; @@ -93,6 +102,7 @@ static int opt_port= 0; static int opt_max_connect_retries; static int opt_max_connections= DEFAULT_MAX_CONN; static my_bool opt_compress= 0, silent= 0, verbose= 0; +static int opt_connect_timeout= -1; static my_bool debug_info_flag= 0, debug_check_flag= 0; static my_bool tty_password= 0; static my_bool opt_mark_progress= 0; @@ -106,6 +116,7 @@ static my_bool display_result_vertically= FALSE, display_result_lower= FALSE, static my_bool disable_query_log= 0, disable_result_log= 0; static my_bool disable_connect_log= 1; static my_bool disable_warnings= 0; +static my_bool prepare_warnings_enabled= 0; static my_bool disable_info= 1; static my_bool abort_on_error= 1; static my_bool server_initialized= 0; @@ -124,6 +135,10 @@ static char delimiter[MAX_DELIMITER_LENGTH]= ";"; static uint delimiter_length= 1; static char TMPDIR[FN_REFLEN]; +static char global_subst_from[200]; +static char global_subst_to[200]; +static char *global_subst= NULL; +static MEM_ROOT require_file_root; /* Block stack */ enum block_cmd { @@ -190,6 +205,10 @@ static void init_re(void); static int match_re(my_regex_t *, char *); static void free_re(void); +static int replace(DYNAMIC_STRING *ds_str, + const char *search_str, ulong search_len, + const char *replace_str, ulong replace_len); + static uint opt_protocol=0; DYNAMIC_ARRAY q_lines; @@ -229,7 +248,7 @@ HASH var_hash; struct st_connection { - MYSQL mysql; + MYSQL *mysql; /* Used when creating views and sp, to avoid implicit commit */ MYSQL* util_mysql; char *name; @@ -245,7 +264,7 @@ struct st_connection pthread_cond_t cond; pthread_t tid; int query_done; - my_bool has_thread; + my_bool has_thread, mutex_inited; #endif /*EMBEDDED_LIBRARY*/ }; @@ -298,6 +317,7 @@ enum enum_commands { Q_LIST_FILES, Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE, Q_SEND_SHUTDOWN, Q_SHUTDOWN_SERVER, Q_MOVE_FILE, Q_REMOVE_FILES_WILDCARD, Q_SEND_EVAL, + Q_ENABLE_PREPARE_WARNINGS, Q_DISABLE_PREPARE_WARNINGS, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ @@ -400,6 +420,8 @@ const char *command_names[]= "move_file", "remove_files_wildcard", "send_eval", + "enable_prepare_warnings", + "disable_prepare_warnings", 0 }; @@ -443,7 +465,7 @@ struct st_command int first_word_len, query_len; my_bool abort_on_error, used_replace; struct st_expected_errors expected_errors; - char require_file[FN_REFLEN]; + char *require_file; enum enum_commands type; }; @@ -534,7 +556,7 @@ public: { DBUG_ENTER("LogFile::open"); DBUG_PRINT("enter", ("dir: '%s', name: '%s'", - dir, name)); + val_or_null(dir), val_or_null(name))); if (!name) { m_file= stdout; @@ -600,14 +622,14 @@ public: lines++; int show_offset= 0; - char buf[256]; + char buf[256+1]; /* + zero termination for DBUG_PRINT */ size_t bytes; bool found_bof= false; /* Search backward in file until "lines" newline has been found */ while (lines && !found_bof) { - show_offset-= sizeof(buf); + show_offset-= sizeof(buf)-1; while(fseek(m_file, show_offset, SEEK_END) != 0 && show_offset < 0) { found_bof= true; @@ -615,7 +637,7 @@ public: show_offset++; } - if ((bytes= fread(buf, 1, sizeof(buf), m_file)) <= 0) + if ((bytes= fread(buf, 1, sizeof(buf)-1, m_file)) <= 0) { // ferror=0 will happen here if no queries executed yet if (ferror(m_file)) @@ -625,6 +647,7 @@ public: DBUG_VOID_RETURN; } + IF_DBUG(buf[bytes]= '\0';) DBUG_PRINT("info", ("Read %lu bytes from file, buf: %s", (unsigned long)bytes, buf)); @@ -669,8 +692,10 @@ public: } } - while ((bytes= fread(buf, 1, sizeof(buf), m_file)) > 0) - fwrite(buf, 1, bytes, stderr); + while ((bytes= fread(buf, 1, sizeof(buf)-1, m_file)) > 0) + if (bytes != fwrite(buf, 1, bytes, stderr)) + die("Failed to write to '%s', errno: %d", + m_file_name, errno); if (!lines) { @@ -711,6 +736,10 @@ void handle_no_error(struct st_command*); #ifdef EMBEDDED_LIBRARY +/* workaround for MySQL BUG#57491 */ +#undef MY_WME +#define MY_WME 0 + /* attributes of the query thread */ pthread_attr_t cn_thd_attrib; @@ -725,8 +754,11 @@ pthread_handler_t send_one_query(void *arg) { struct st_connection *cn= (struct st_connection*)arg; + if (!cn->mysql) + return 0; + mysql_thread_init(); - VOID(mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len)); + VOID(mysql_send_query(cn->mysql, cn->cur_query, cn->cur_query_len)); mysql_thread_end(); pthread_mutex_lock(&cn->mutex); @@ -740,13 +772,18 @@ pthread_handler_t send_one_query(void *arg) static int do_send_query(struct st_connection *cn, const char *q, int q_len, int flags) { + if (!cn->mysql) + die("Trying to send a query without a connection"); + if (flags & QUERY_REAP_FLAG) - return mysql_send_query(&cn->mysql, q, q_len); + return mysql_send_query(cn->mysql, q, q_len); - if (pthread_mutex_init(&cn->mutex, NULL) || - pthread_cond_init(&cn->cond, NULL)) + if (!cn->mutex_inited && + (pthread_mutex_init(&cn->mutex, NULL) || + pthread_cond_init(&cn->cond, NULL))) die("Error in the thread library"); + cn->mutex_inited= 1; cn->cur_query= q; cn->cur_query_len= q_len; cn->query_done= 0; @@ -776,9 +813,20 @@ static void wait_query_thread_end(struct st_connection *con) } } +static void free_embedded_data(struct st_connection *con) +{ + if (con->mutex_inited) + { + con->mutex_inited= 0; + pthread_mutex_destroy(&con->mutex); + pthread_cond_destroy(&con->cond); + } +} + #else /*EMBEDDED_LIBRARY*/ -#define do_send_query(cn,q,q_len,flags) mysql_send_query(&cn->mysql, q, q_len) +#define do_send_query(cn,q,q_len,flags) mysql_send_query(cn->mysql, q, q_len) +#define free_embedded_data(next_con) do { } while(0) #endif /*EMBEDDED_LIBRARY*/ @@ -1080,7 +1128,8 @@ void check_command_args(struct st_command *command, DBUG_VOID_RETURN; } -void handle_command_error(struct st_command *command, uint error) +void handle_command_error(struct st_command *command, uint error, + int sys_errno) { DBUG_ENTER("handle_command_error"); DBUG_PRINT("enter", ("error: %d", error)); @@ -1089,20 +1138,22 @@ void handle_command_error(struct st_command *command, uint error) int i; if (command->abort_on_error) - die("command \"%.*s\" failed with error %d. my_errno=%d", - command->first_word_len, command->query, error, my_errno); + die("command \"%.*s\" failed with error: %u my_errno: %d errno: %d", + command->first_word_len, command->query, error, my_errno, + sys_errno); i= match_expected_error(command, error, NULL); if (i >= 0) { - DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %d", - command->first_word_len, command->query, error)); + DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %u, errno: %d", + command->first_word_len, command->query, error, + sys_errno)); DBUG_VOID_RETURN; } if (command->expected_errors.count > 0) - die("command \"%.*s\" failed with wrong error: %d. my_errno=%d", - command->first_word_len, command->query, error, my_errno); + die("command \"%.*s\" failed with wrong error: %u my_errno: %d errno: %d", + command->first_word_len, command->query, error, my_errno, sys_errno); } else if (command->expected_errors.err[0].type == ERR_ERRNO && command->expected_errors.err[0].code.errnum != 0) @@ -1124,10 +1175,12 @@ void close_connections() if (next_con->stmt) mysql_stmt_close(next_con->stmt); next_con->stmt= 0; - mysql_close(&next_con->mysql); + mysql_close(next_con->mysql); + next_con->mysql= 0; if (next_con->util_mysql) mysql_close(next_con->util_mysql); my_free(next_con->name, MYF(MY_ALLOW_ZERO_PTR)); + free_embedded_data(next_con); } my_free(connections, MYF(MY_WME)); DBUG_VOID_RETURN; @@ -1195,25 +1248,23 @@ void free_used_memory() free_all_replace(); my_free(opt_pass,MYF(MY_ALLOW_ZERO_PTR)); free_defaults(default_argv); + free_root(&require_file_root, MYF(0)); free_re(); #ifdef __WIN__ free_tmp_sh_file(); free_win_path_patterns(); #endif - - /* Only call mysql_server_end if mysql_server_init has been called */ - if (server_initialized) - mysql_server_end(); - - /* Don't use DBUG after mysql_server_end() */ - DBUG_VIOLATION_HELPER_LEAVE; - return; + DBUG_VOID_RETURN; } static void cleanup_and_exit(int exit_code) { free_used_memory(); + + /* Only call mysql_server_end if mysql_server_init has been called */ + if (server_initialized) + mysql_server_end(); my_end(my_end_arg); if (!silent) { @@ -1238,12 +1289,17 @@ static void cleanup_and_exit(int exit_code) void print_file_stack() { - for (struct st_test_file* err_file= cur_file; - err_file != file_stack; - err_file--) + struct st_test_file* err_file= cur_file; + if (err_file == file_stack) + return; + + for (;;) { + err_file--; fprintf(stderr, "included from %s at line %d:\n", err_file->file_name, err_file->lineno); + if (err_file == file_stack) + break; } } @@ -1254,15 +1310,6 @@ void die(const char *fmt, ...) DBUG_ENTER("die"); DBUG_PRINT("enter", ("start_lineno: %d", start_lineno)); - /* - Protect against dying twice - first time 'die' is called, try to write log files - second time, just exit - */ - if (dying) - cleanup_and_exit(1); - dying= 1; - /* Print the error message */ fprintf(stderr, "mysqltest: "); if (cur_file && cur_file != file_stack) @@ -1271,7 +1318,6 @@ void die(const char *fmt, ...) cur_file->file_name); print_file_stack(); } - if (start_lineno > 0) fprintf(stderr, "At line %u: ", start_lineno); if (fmt) @@ -1285,6 +1331,15 @@ void die(const char *fmt, ...) fprintf(stderr, "\n"); fflush(stderr); + /* + Protect against dying twice + first time 'die' is called, try to write log files + second time, just exit + */ + if (dying) + cleanup_and_exit(1); + dying= 1; + log_file.show_tail(opt_tail_lines); /* @@ -1292,7 +1347,7 @@ void die(const char *fmt, ...) been produced prior to the error */ if (cur_con && !cur_con->pending) - show_warnings_before_error(&cur_con->mysql); + show_warnings_before_error(cur_con->mysql); cleanup_and_exit(1); } @@ -1304,6 +1359,7 @@ void abort_not_supported_test(const char *fmt, ...) DBUG_ENTER("abort_not_supported_test"); /* Print include filestack */ + fflush(stdout); fprintf(stderr, "The test '%s' is not supported by this installation\n", file_stack->file_name); fprintf(stderr, "Detected in file %s at line %d\n", @@ -1335,6 +1391,8 @@ void verbose_msg(const char *fmt, ...) { va_list args; DBUG_ENTER("verbose_msg"); + DBUG_PRINT("enter", ("format: %s", fmt)); + if (!verbose) DBUG_VOID_RETURN; @@ -1690,49 +1748,69 @@ enum compare_files_result_enum { */ -int compare_files2(File fd, const char* filename2) +int compare_files2(File fd1, const char* filename2) { int error= RESULT_OK; File fd2; - size_t len, len2; - char buff[512], buff2[512]; + size_t fd1_length, fd2_length; + DYNAMIC_STRING fd1_result, fd2_result; if ((fd2= my_open(filename2, O_RDONLY, MYF(0))) < 0) { - my_close(fd, MYF(0)); + my_close(fd1, MYF(0)); die("Failed to open second file: '%s'", filename2); } - while((len= my_read(fd, (uchar*)&buff, - sizeof(buff), MYF(0))) > 0) - { - if ((len2= my_read(fd2, (uchar*)&buff2, - sizeof(buff2), MYF(0))) < len) - { - /* File 2 was smaller */ - error= RESULT_LENGTH_MISMATCH; - break; - } - if (len2 > len) - { - /* File 1 was smaller */ - error= RESULT_LENGTH_MISMATCH; - break; - } - if ((memcmp(buff, buff2, len))) - { - /* Content of this part differed */ - error= RESULT_CONTENT_MISMATCH; - break; - } + + fd1_length= (size_t) my_seek(fd1, 0, SEEK_END, MYF(0)); + fd2_length= (size_t) my_seek(fd2, 0, SEEK_END, MYF(0)); + + if (init_dynamic_string(&fd1_result, 0, fd1_length, 0) || + init_dynamic_string(&fd2_result, 0, fd2_length, 0)) + die("Out of memory when allocating data for result"); + + fd1_result.length= fd1_length; + fd2_result.length= fd2_length; + + (void) my_seek(fd1, 0, SEEK_SET, MYF(0)); + (void) my_seek(fd2, 0, SEEK_SET, MYF(0)); + if (my_read(fd1, (uchar*) fd1_result.str, fd1_length, MYF(MY_WME | MY_NABP))) + die("Error when reading data from result file"); + if (my_read(fd2, (uchar*) fd2_result.str, fd2_length, MYF(MY_WME | MY_NABP))) + die("Error when reading data from result file"); + + if (global_subst && + (fd1_length != fd2_length || + memcmp(fd1_result.str, fd2_result.str, fd1_length))) + { + /** + @todo MARIA_HACK + This serves for when a test is run with --default-storage-engine=X + where X is not MyISAM: tests using SHOW CREATE TABLE will always fail + because SHOW CREATE TABLE prints X instead of MyISAM. With + --global-subst=X,MyISAM , such trivial differences are eliminated and + test may be reported as passing. + --global-subst is only a quick way to run a lot of existing tests + with Maria and find bugs; it is not good enough for reaching the main + trees when Maria is merged into them. + --global-subst should be removed. + */ + uint global_subst_from_len= strlen(global_subst_from); + uint global_subst_to_len= strlen(global_subst_to); + while (replace(&fd1_result, + global_subst_from, global_subst_from_len, + global_subst_to, global_subst_to_len) == 0) + /* do nothing */ ; + /* let's compare again to see if it is ok now */ } - if (!error && my_read(fd2, (uchar*)&buff2, - sizeof(buff2), MYF(0)) > 0) - { - /* File 1 was smaller */ + + if (fd1_result.length != fd2_result.length) error= RESULT_LENGTH_MISMATCH; - } + else if ((memcmp(fd1_result.str, fd2_result.str, fd1_result.length))) + error= RESULT_CONTENT_MISMATCH; my_close(fd2, MYF(0)); + dynstr_free(&fd1_result); + dynstr_free(&fd2_result); return error; } @@ -1800,7 +1878,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) { my_close(fd, MYF(0)); /* Remove the temporary file */ - my_delete(temp_file_path, MYF(0)); + my_delete(temp_file_path, MYF(MY_WME)); die("Failed to write file '%s'", temp_file_path); } @@ -1808,7 +1886,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) my_close(fd, MYF(0)); /* Remove the temporary file */ - my_delete(temp_file_path, MYF(0)); + my_delete(temp_file_path, MYF(MY_WME)); DBUG_RETURN(error); } @@ -1852,7 +1930,7 @@ void check_result() if (access(reject_file, W_OK) == 0) { /* Result file directory is writable, save reject file there */ - fn_format(reject_file, result_file_name, NULL, + fn_format(reject_file, result_file_name, "", ".reject", MY_REPLACE_EXT); } else @@ -1975,18 +2053,20 @@ VAR *var_init(VAR *v, const char *name, int name_len, const char *val, + name_len+2, MYF(MY_WME)))) die("Out of memory"); - tmp_var->name = (name) ? (char*) tmp_var + sizeof(*tmp_var) : 0; + if (name != NULL) + { + tmp_var->name= reinterpret_cast<char*>(tmp_var) + sizeof(*tmp_var); + memcpy(tmp_var->name, name, name_len); + tmp_var->name[name_len]= 0; + } + else + tmp_var->name= NULL; + tmp_var->alloced = (v == 0); if (!(tmp_var->str_val = (char*)my_malloc(val_alloc_len+1, MYF(MY_WME)))) die("Out of memory"); - if (name) - { - memcpy(tmp_var->name, name, name_len); - tmp_var->name[name_len]= 0; - } - if (val) { memcpy(tmp_var->str_val, val, val_len); @@ -2192,7 +2272,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end) *query_end : query + strlen(query)); MYSQL_RES *res; MYSQL_ROW row; - MYSQL* mysql = &cur_con->mysql; + MYSQL* mysql = cur_con->mysql; DYNAMIC_STRING ds_query; DBUG_ENTER("var_query_set"); LINT_INIT(res); @@ -2288,7 +2368,7 @@ void var_set_query_get_value(struct st_command *command, VAR *var) long row_no; int col_no= -1; MYSQL_RES* res; - MYSQL* mysql= &cur_con->mysql; + MYSQL* mysql= cur_con->mysql; static DYNAMIC_STRING ds_query; static DYNAMIC_STRING ds_col; @@ -2985,8 +3065,8 @@ void do_remove_file(struct st_command *command) ' '); DBUG_PRINT("info", ("removing file: %s", ds_filename.str)); - error= my_delete(ds_filename.str, MYF(0)) != 0; - handle_command_error(command, error); + error= my_delete_allow_opened(ds_filename.str, MYF(disable_warnings ? 0 : MY_WME)) != 0; + handle_command_error(command, error, my_errno); dynstr_free(&ds_filename); DBUG_VOID_RETURN; } @@ -3004,8 +3084,9 @@ void do_remove_file(struct st_command *command) void do_remove_files_wildcard(struct st_command *command) { - int error= 0; + int error= 0, sys_errno= 0; uint i; + size_t directory_length; MY_DIR *dir_info; FILEINFO *file; char dir_separator[2]; @@ -3028,15 +3109,16 @@ void do_remove_files_wildcard(struct st_command *command) DBUG_PRINT("info", ("listing directory: %s", dirname)); /* Note that my_dir sorts the list if not given any flags */ - if (!(dir_info= my_dir(dirname, MYF(MY_DONT_SORT | MY_WANT_STAT)))) + if (!(dir_info= my_dir(dirname, MYF(MY_DONT_SORT | MY_WANT_STAT | MY_WME)))) { error= 1; + sys_errno= my_errno; goto end; } init_dynamic_string(&ds_file_to_remove, dirname, 1024, 1024); dir_separator[0]= FN_LIBCHAR; - dir_separator[1]= 0; - dynstr_append(&ds_file_to_remove, dir_separator); + dynstr_append_mem(&ds_file_to_remove, dir_separator, 1); + directory_length= ds_file_to_remove.length; /* Set default wild chars for wild_compare, is changed in embedded mode */ set_wild_chars(1); @@ -3052,11 +3134,11 @@ void do_remove_files_wildcard(struct st_command *command) if (ds_wild.length && wild_compare(file->name, ds_wild.str, 0)) continue; - ds_file_to_remove.length= ds_directory.length + 1; - ds_file_to_remove.str[ds_directory.length + 1]= 0; + ds_file_to_remove.length= directory_length; dynstr_append(&ds_file_to_remove, file->name); DBUG_PRINT("info", ("removing file: %s", ds_file_to_remove.str)); - error= my_delete(ds_file_to_remove.str, MYF(0)) != 0; + if ((error= (my_delete(ds_file_to_remove.str, MYF(MY_WME)) != 0))) + sys_errno= my_errno; if (error) break; } @@ -3064,7 +3146,7 @@ void do_remove_files_wildcard(struct st_command *command) my_dirend(dir_info); end: - handle_command_error(command, error); + handle_command_error(command, error, sys_errno); dynstr_free(&ds_directory); dynstr_free(&ds_wild); dynstr_free(&ds_file_to_remove); @@ -3102,8 +3184,8 @@ void do_copy_file(struct st_command *command) DBUG_PRINT("info", ("Copy %s to %s", ds_from_file.str, ds_to_file.str)); error= (my_copy(ds_from_file.str, ds_to_file.str, - MYF(MY_DONT_OVERWRITE_FILE)) != 0); - handle_command_error(command, error); + MYF(MY_DONT_OVERWRITE_FILE | MY_WME)) != 0); + handle_command_error(command, error, my_errno); dynstr_free(&ds_from_file); dynstr_free(&ds_to_file); DBUG_VOID_RETURN; @@ -3138,8 +3220,8 @@ void do_move_file(struct st_command *command) DBUG_PRINT("info", ("Move %s to %s", ds_from_file.str, ds_to_file.str)); error= (my_rename(ds_from_file.str, ds_to_file.str, - MYF(0)) != 0); - handle_command_error(command, error); + MYF(disable_warnings ? 0 : MY_WME)) != 0); + handle_command_error(command, error, my_errno); dynstr_free(&ds_from_file); dynstr_free(&ds_to_file); DBUG_VOID_RETURN; @@ -3159,6 +3241,7 @@ void do_move_file(struct st_command *command) void do_chmod_file(struct st_command *command) { + int error; long mode= 0; static DYNAMIC_STRING ds_mode; static DYNAMIC_STRING ds_file; @@ -3179,7 +3262,10 @@ void do_chmod_file(struct st_command *command) die("You must write a 4 digit octal number for mode"); DBUG_PRINT("info", ("chmod %o %s", (uint)mode, ds_file.str)); - handle_command_error(command, chmod(ds_file.str, mode)); + error= 0; + if (chmod(ds_file.str, mode)) + error= 1; + handle_command_error(command, error, errno); dynstr_free(&ds_mode); dynstr_free(&ds_file); DBUG_VOID_RETURN; @@ -3212,7 +3298,7 @@ void do_file_exist(struct st_command *command) DBUG_PRINT("info", ("Checking for existence of file: %s", ds_filename.str)); error= (access(ds_filename.str, F_OK) != 0); - handle_command_error(command, error); + handle_command_error(command, error, errno); dynstr_free(&ds_filename); DBUG_VOID_RETURN; } @@ -3242,8 +3328,8 @@ void do_mkdir(struct st_command *command) ' '); DBUG_PRINT("info", ("creating directory: %s", ds_dirname.str)); - error= my_mkdir(ds_dirname.str, 0777, MYF(0)) != 0; - handle_command_error(command, error); + error= my_mkdir(ds_dirname.str, 0777, MYF(MY_WME)) != 0; + handle_command_error(command, error, my_errno); dynstr_free(&ds_dirname); DBUG_VOID_RETURN; } @@ -3263,7 +3349,7 @@ 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"} + { "dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to remove" } }; DBUG_ENTER("do_rmdir"); @@ -3273,7 +3359,7 @@ void do_rmdir(struct st_command *command) DBUG_PRINT("info", ("removing directory: %s", ds_dirname.str)); error= rmdir(ds_dirname.str) != 0; - handle_command_error(command, error); + handle_command_error(command, error, errno); dynstr_free(&ds_dirname); DBUG_VOID_RETURN; } @@ -3350,7 +3436,7 @@ static void do_list_files(struct st_command *command) sizeof(list_files_args)/sizeof(struct command_arg), ' '); error= get_list_files(&ds_res, &ds_dirname, &ds_wild); - handle_command_error(command, error); + handle_command_error(command, error, my_errno); dynstr_free(&ds_dirname); dynstr_free(&ds_wild); DBUG_VOID_RETURN; @@ -3393,7 +3479,7 @@ static void do_list_files_write_file_command(struct st_command *command, init_dynamic_string(&ds_content, "", 1024, 1024); error= get_list_files(&ds_content, &ds_dirname, &ds_wild); - handle_command_error(command, error); + handle_command_error(command, error, my_errno); str_to_file2(ds_filename.str, ds_content.str, ds_content.length, append); dynstr_free(&ds_content); dynstr_free(&ds_filename); @@ -3617,7 +3703,7 @@ void do_cat_file(struct st_command *command) DBUG_PRINT("info", ("Reading from, file: %s", ds_filename.str)); error= cat_file(&ds_res, ds_filename.str); - handle_command_error(command, error); + handle_command_error(command, error, my_errno); dynstr_free(&ds_filename); DBUG_VOID_RETURN; } @@ -3663,9 +3749,10 @@ void do_diff_files(struct st_command *command) if ((error= compare_files(ds_filename.str, ds_filename2.str)) && match_expected_error(command, error, NULL) < 0) { - /* Compare of the two files failed, append them to output - so the failure can be analyzed, but only if it was not - expected to fail. + /* + Compare of the two files failed, append them to output + so the failure can be analyzed, but only if it was not + expected to fail. */ show_diff(&ds_res, ds_filename.str, ds_filename2.str); log_file.write(&ds_res); @@ -3675,7 +3762,7 @@ void do_diff_files(struct st_command *command) dynstr_free(&ds_filename); dynstr_free(&ds_filename2); - handle_command_error(command, error); + handle_command_error(command, error, -1); DBUG_VOID_RETURN; } @@ -3725,7 +3812,7 @@ void do_send_quit(struct st_command *command) if (!(con= find_connection_by_name(name))) die("connection '%s' not found in connection pool", name); - simple_command(&con->mysql,COM_QUIT,0,0,1); + simple_command(con->mysql,COM_QUIT,0,0,1); DBUG_VOID_RETURN; } @@ -3749,7 +3836,7 @@ void do_send_quit(struct st_command *command) void do_change_user(struct st_command *command) { - MYSQL *mysql = &cur_con->mysql; + MYSQL *mysql = cur_con->mysql; /* static keyword to make the NetWare compiler happy. */ static DYNAMIC_STRING ds_user, ds_passwd, ds_db; const struct command_arg change_user_args[] = { @@ -3882,7 +3969,7 @@ void do_perl(struct st_command *command) /* Remove the temporary file, but keep it if perl failed */ if (!error) - my_delete(temp_file_path, MYF(0)); + my_delete(temp_file_path, MYF(MY_WME)); /* Check for error code that indicates perl could not be started */ int exstat= WEXITSTATUS(error); @@ -3895,7 +3982,7 @@ void do_perl(struct st_command *command) abort_not_supported_test("perl not found in path"); #endif else - handle_command_error(command, exstat); + handle_command_error(command, WEXITSTATUS(error), my_errno); } dynstr_free(&ds_delimiter); DBUG_VOID_RETURN; @@ -3944,7 +4031,7 @@ int do_echo(struct st_command *command) void do_wait_for_slave_to_stop(struct st_command *c __attribute__((unused))) { static int SLAVE_POLL_INTERVAL= 300000; - MYSQL* mysql = &cur_con->mysql; + MYSQL* mysql = cur_con->mysql; for (;;) { MYSQL_RES *UNINIT_VAR(res); @@ -3974,7 +4061,7 @@ void do_sync_with_master2(struct st_command *command, long offset) { MYSQL_RES *res; MYSQL_ROW row; - MYSQL *mysql= &cur_con->mysql; + MYSQL *mysql= cur_con->mysql; char query_buf[FN_REFLEN+128]; int timeout= 300; /* seconds */ @@ -4064,7 +4151,7 @@ int do_save_master_pos() { MYSQL_RES *res; MYSQL_ROW row; - MYSQL *mysql = &cur_con->mysql; + MYSQL *mysql = cur_con->mysql; const char *query; int rpl_parse; DBUG_ENTER("do_save_master_pos"); @@ -4290,22 +4377,22 @@ void do_let(struct st_command *command) int do_rpl_probe(struct st_command *command __attribute__((unused))) { DBUG_ENTER("do_rpl_probe"); - if (mysql_rpl_probe(&cur_con->mysql)) - die("Failed in mysql_rpl_probe(): '%s'", mysql_error(&cur_con->mysql)); + if (mysql_rpl_probe(cur_con->mysql)) + die("Failed in mysql_rpl_probe(): '%s'", mysql_error(cur_con->mysql)); DBUG_RETURN(0); } int do_enable_rpl_parse(struct st_command *command __attribute__((unused))) { - mysql_enable_rpl_parse(&cur_con->mysql); + mysql_enable_rpl_parse(cur_con->mysql); return 0; } int do_disable_rpl_parse(struct st_command *command __attribute__((unused))) { - mysql_disable_rpl_parse(&cur_con->mysql); + mysql_disable_rpl_parse(cur_con->mysql); return 0; } @@ -4482,7 +4569,7 @@ void do_shutdown_server(struct st_command *command) long timeout=60; int pid; DYNAMIC_STRING ds_pidfile_name; - MYSQL* mysql = &cur_con->mysql; + MYSQL* mysql = cur_con->mysql; static DYNAMIC_STRING ds_timeout; const struct command_arg shutdown_args[] = { {"timeout", ARG_STRING, FALSE, &ds_timeout, "Timeout before killing server"} @@ -4824,7 +4911,7 @@ void set_current_connection(struct st_connection *con) cur_con= con; /* Update $mysql_get_server_version to that of current connection */ var_set_int("$mysql_get_server_version", - mysql_get_server_version(&con->mysql)); + mysql_get_server_version(con->mysql)); /* Update $CURRENT_CONNECTION to the name of the current connection */ var_set_string("$CURRENT_CONNECTION", con->name); } @@ -4875,7 +4962,7 @@ void select_connection(struct st_command *command) void do_close_connection(struct st_command *command) { - DBUG_ENTER("close_connection"); + DBUG_ENTER("do_close_connection"); struct st_connection *con; static DYNAMIC_STRING ds_connection; @@ -4897,10 +4984,10 @@ void do_close_connection(struct st_command *command) #ifndef EMBEDDED_LIBRARY if (command->type == Q_DIRTY_CLOSE) { - if (con->mysql.net.vio) + if (con->mysql->net.vio) { - vio_delete(con->mysql.net.vio); - con->mysql.net.vio = 0; + vio_delete(con->mysql->net.vio); + con->mysql->net.vio = 0; } } #else @@ -4915,14 +5002,16 @@ void do_close_connection(struct st_command *command) mysql_stmt_close(con->stmt); con->stmt= 0; - mysql_close(&con->mysql); + mysql_close(con->mysql); + con->mysql= 0; + free_embedded_data(con); if (con->util_mysql) mysql_close(con->util_mysql); con->util_mysql= 0; con->pending= FALSE; - my_free(con->name, MYF(0)); + my_free(con->name, MYF(MY_ALLOW_ZERO_PTR)); /* When the connection is closed set name to "-closed_connection-" @@ -4948,6 +5037,7 @@ void do_close_connection(struct st_command *command) dynstr_append_mem(ds, ";\n", 2); } + dynstr_free(&ds_connection); DBUG_VOID_RETURN; } @@ -5168,7 +5258,8 @@ void do_connect(struct st_command *command) int con_port= opt_port; char *con_options; my_bool con_ssl= 0, con_compress= 0; - my_bool con_pipe= 0, con_shm= 0; + my_bool con_pipe= 0; + my_bool con_shm __attribute__ ((unused))= 0; struct st_connection* con_slot; static DYNAMIC_STRING ds_connection_name; @@ -5240,7 +5331,8 @@ void do_connect(struct st_command *command) con_options= ds_options.str; while (*con_options) { - char* end; + size_t length; + char *end; /* Step past any spaces in beginning of option*/ while (*con_options && my_isspace(charset_info, *con_options)) con_options++; @@ -5248,13 +5340,14 @@ void do_connect(struct st_command *command) end= con_options; while (*end && !my_isspace(charset_info, *end)) end++; - if (!strncmp(con_options, "SSL", 3)) + length= (size_t) (end - con_options); + if (length == 3 && !strncmp(con_options, "SSL", 3)) con_ssl= 1; - else if (!strncmp(con_options, "COMPRESS", 8)) + else if (length == 8 && !strncmp(con_options, "COMPRESS", 8)) con_compress= 1; - else if (!strncmp(con_options, "PIPE", 4)) + else if (length == 4 && !strncmp(con_options, "PIPE", 4)) con_pipe= 1; - else if (!strncmp(con_options, "SHM", 3)) + else if (length == 3 && !strncmp(con_options, "SHM", 3)) con_shm= 1; else die("Illegal option to connect: %.*s", @@ -5273,22 +5366,27 @@ void do_connect(struct st_command *command) if (!(con_slot= find_connection_by_name("-closed_connection-"))) die("Connection limit exhausted, you can have max %d connections", opt_max_connections); + my_free(con_slot->name, MYF(0)); + con_slot->name= 0; } #ifdef EMBEDDED_LIBRARY con_slot->query_done= 1; con_slot->has_thread= FALSE; #endif - if (!mysql_init(&con_slot->mysql)) + if (!(con_slot->mysql= mysql_init(0))) die("Failed on mysql_init()"); if (opt_compress || con_compress) - mysql_options(&con_slot->mysql, MYSQL_OPT_COMPRESS, NullS); - mysql_options(&con_slot->mysql, MYSQL_OPT_LOCAL_INFILE, 0); - mysql_options(&con_slot->mysql, MYSQL_SET_CHARSET_NAME, + mysql_options(con_slot->mysql, MYSQL_OPT_COMPRESS, NullS); + mysql_options(con_slot->mysql, MYSQL_OPT_LOCAL_INFILE, 0); + mysql_options(con_slot->mysql, MYSQL_SET_CHARSET_NAME, charset_info->csname); if (opt_charsets_dir) - mysql_options(&con_slot->mysql, MYSQL_SET_CHARSET_DIR, + mysql_options(con_slot->mysql, MYSQL_SET_CHARSET_DIR, opt_charsets_dir); + if (opt_connect_timeout >= 0) + mysql_options(con_slot->mysql, MYSQL_OPT_CONNECT_TIMEOUT, + &opt_connect_timeout); #ifdef HAVE_OPENSSL if (opt_use_ssl) @@ -5298,12 +5396,12 @@ void do_connect(struct st_command *command) if (con_ssl) { #ifdef HAVE_OPENSSL - mysql_ssl_set(&con_slot->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, + mysql_ssl_set(con_slot->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); #if MYSQL_VERSION_ID >= 50000 /* Turn on ssl_verify_server_cert only if host is "localhost" */ opt_ssl_verify_server_cert= !strcmp(ds_host.str, "localhost"); - mysql_options(&con_slot->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, + mysql_options(con_slot->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &opt_ssl_verify_server_cert); #endif #endif @@ -5317,22 +5415,20 @@ void do_connect(struct st_command *command) } if (opt_protocol) - mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol); + mysql_options(con_slot->mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol); +#ifdef HAVE_SMEM if (con_shm) { -#ifdef HAVE_SMEM uint protocol= MYSQL_PROTOCOL_MEMORY; if (!ds_shm.length) die("Missing shared memory base name"); - mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, ds_shm.str); - mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol); -#endif + mysql_options(con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, ds_shm.str); + mysql_options(con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol); } -#ifdef HAVE_SMEM else if (shared_memory_base_name) { - mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, + mysql_options(con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, shared_memory_base_name); } #endif @@ -5345,7 +5441,7 @@ void do_connect(struct st_command *command) if (ds_database.length && !strcmp(ds_database.str,"*NO-ONE*")) dynstr_set(&ds_database, ""); - if (connect_n_handle_errors(command, &con_slot->mysql, + if (connect_n_handle_errors(command, con_slot->mysql, ds_host.str,ds_user.str, ds_password.str, ds_database.str, con_port, ds_sock.str)) @@ -6036,6 +6132,11 @@ static struct my_option my_long_options[] = {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", &debug_info_flag, &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"global-subst", OPT_GLOBAL_SUBST, "argument should be 'X,Y' ;" + " substitute string X with another Y accross the whole test's current" + " result before comparing with expected result file", + &global_subst, &global_subst, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", &opt_host, &opt_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"include", 'i', "Include SQL before each test case.", &opt_include, @@ -6053,7 +6154,7 @@ static struct my_option my_long_options[] = {"max-connections", OPT_MAX_CONNECTIONS, "Max number of open connections to server", &opt_max_connections, &opt_max_connections, 0, - GET_INT, REQUIRED_ARG, 128, 8, 5120, 0, 0, 0}, + GET_INT, REQUIRED_ARG, DEFAULT_MAX_CONN, 8, 5120, 0, 0, 0}, {"password", 'p', "Password to use when connecting to server.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).", @@ -6107,6 +6208,9 @@ static struct my_option my_long_options[] = GET_INT, REQUIRED_ARG, 0, 0, 10000, 0, 0, 0}, {"test-file", 'x', "Read test from/in this file (default stdin).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"connect-timeout", OPT_MY_CONNECT_TIMEOUT, "Client connection timeout", + (uchar**) &opt_connect_timeout, (uchar**) &opt_connect_timeout, 0, + GET_INT, REQUIRED_ARG, -1, -1, 0, 0, 0, 0}, {"timer-file", 'm', "File where the timing in microseconds is stored.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"tmpdir", 't', "Temporary directory where sockets are put.", @@ -6201,6 +6305,7 @@ get_one_option(int optid, const struct my_option *opt, #ifndef DBUG_OFF DBUG_PUSH(argument ? argument : "d:t:S:i:O,/tmp/mysqltest.trace"); debug_check_flag= 1; + debug_info_flag= 1; #endif break; case 'r': @@ -6316,8 +6421,17 @@ int parse_args(int argc, char **argv) if (debug_info_flag) my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; if (debug_check_flag) - my_end_arg= MY_CHECK_ERROR; + my_end_arg|= MY_CHECK_ERROR; + if (global_subst != NULL) + { + char *comma= strstr(global_subst, ","); + if (comma == NULL) + die("wrong --global-subst, must be X,Y"); + memcpy(global_subst_from, global_subst, (comma-global_subst)); + global_subst_from[comma-global_subst]= 0; + memcpy(global_subst_to, comma+1, strlen(comma)); + } if (!record) { @@ -6808,12 +6922,22 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings) { MYSQL_RES *res= 0; - MYSQL *mysql= &cn->mysql; + MYSQL *mysql= cn->mysql; int err= 0, counter= 0; DBUG_ENTER("run_query_normal"); DBUG_PRINT("enter",("flags: %d", flags)); DBUG_PRINT("enter", ("query: '%-.60s'", query)); + if (!mysql) + { + /* Emulate old behaviour of sending something on a closed connection */ + handle_error(command, 2006, "MySQL server has gone away", + "000000", ds); + cn->pending= FALSE; + var_set_errno(2006); + DBUG_VOID_RETURN; + } + if (flags & QUERY_SEND_FLAG) { /* @@ -7015,7 +7139,7 @@ void handle_error(struct st_command *command, DBUG_ENTER("handle_error"); - if (command->require_file[0]) + if (command->require_file) { /* The query after a "--require" failed. This is fine as long the server @@ -7248,6 +7372,9 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command, handle_no_error(command); if (!disable_result_log) { + ulonglong affected_rows; + LINT_INIT(affected_rows); + /* Not all statements creates a result set. If there is one we can now create another normal result set that contains the meta @@ -7271,10 +7398,15 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command, mysql_free_result(res); /* Free normal result set with meta data */ /* - Clear prepare warnings if there are execute warnings, - since they are probably duplicated. + Normally, if there is a result set, we do not show warnings from the + prepare phase. This is because some warnings are generated both during + prepare and execute; this would generate different warning output + between normal and ps-protocol test runs. + + The --enable_prepare_warnings command can be used to change this so + that warnings from both the prepare and execute phase are shown. */ - if (ds_execute_warnings.length || mysql->warning_count) + if (!disable_warnings && !prepare_warnings_enabled) dynstr_set(&ds_prepare_warnings, NULL); } else @@ -7288,38 +7420,33 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command, Need to grab affected rows information before getting warnings here */ - { - ulonglong UNINIT_VAR(affected_rows); + if (!disable_info) + affected_rows= mysql_affected_rows(mysql); - if (!disable_info) - affected_rows= mysql_affected_rows(mysql); + if (!disable_warnings) + { + /* Get the warnings from execute */ - if (!disable_warnings) + /* Append warnings to ds - if there are any */ + if (append_warnings(&ds_execute_warnings, mysql) || + ds_execute_warnings.length || + ds_prepare_warnings.length || + ds_warnings->length) { - /* Get the warnings from execute */ - - /* Append warnings to ds - if there are any */ - if (append_warnings(&ds_execute_warnings, mysql) || - ds_execute_warnings.length || - ds_prepare_warnings.length || - ds_warnings->length) - { - dynstr_append_mem(ds, "Warnings:\n", 10); - if (ds_warnings->length) - dynstr_append_mem(ds, ds_warnings->str, - ds_warnings->length); - if (ds_prepare_warnings.length) - dynstr_append_mem(ds, ds_prepare_warnings.str, - ds_prepare_warnings.length); - if (ds_execute_warnings.length) - dynstr_append_mem(ds, ds_execute_warnings.str, - ds_execute_warnings.length); - } + dynstr_append_mem(ds, "Warnings:\n", 10); + if (ds_warnings->length) + dynstr_append_mem(ds, ds_warnings->str, + ds_warnings->length); + if (ds_prepare_warnings.length) + dynstr_append_mem(ds, ds_prepare_warnings.str, + ds_prepare_warnings.length); + if (ds_execute_warnings.length) + dynstr_append_mem(ds, ds_execute_warnings.str, + ds_execute_warnings.length); } - - if (!disable_info) - append_info(ds, affected_rows, mysql_info(mysql)); } + if (!disable_info) + append_info(ds, affected_rows, mysql_info(mysql)); } end: @@ -7329,14 +7456,6 @@ end: dynstr_free(&ds_execute_warnings); } - - /* Close the statement if - no reconnect, need new prepare */ - if (mysql->reconnect) - { - mysql_stmt_close(stmt); - cur_con->stmt= NULL; - } - /* We save the return code (mysql_stmt_errno(stmt)) from the last call sent to the server into the mysqltest builtin variable $mysql_errno. This @@ -7345,6 +7464,13 @@ end: var_set_errno(mysql_stmt_errno(stmt)); + /* Close the statement if reconnect, need new prepare */ + if (mysql->reconnect) + { + mysql_stmt_close(stmt); + cur_con->stmt= NULL; + } + DBUG_VOID_RETURN; } @@ -7397,7 +7523,7 @@ int util_query(MYSQL* org_mysql, const char* query){ void run_query(struct st_connection *cn, struct st_command *command, int flags) { - MYSQL *mysql= &cn->mysql; + MYSQL *mysql= cn->mysql; DYNAMIC_STRING *ds; DYNAMIC_STRING *save_ds= NULL; DYNAMIC_STRING ds_result; @@ -7440,7 +7566,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) Create a temporary dynamic string to contain the output from this query. */ - if (command->require_file[0]) + if (command->require_file) { init_dynamic_string(&ds_result, "", 1024, 1024); ds= &ds_result; @@ -7502,7 +7628,6 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) } dynstr_free(&query_str); - } if (sp_protocol_enabled && @@ -7599,7 +7724,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) mysql_errno(mysql), mysql_error(mysql)); } - if (command->require_file[0]) + if (command->require_file) { /* A result file was specified for _this_ query and the output should be checked against an already @@ -7928,7 +8053,6 @@ static void init_signal_handling(void) #endif sigaction(SIGILL, &sa, NULL); sigaction(SIGFPE, &sa, NULL); - DBUG_VOID_RETURN; } @@ -7940,7 +8064,9 @@ int main(int argc, char **argv) my_bool q_send_flag= 0, abort_flag= 0; uint command_executed= 0, last_command_executed= 0; char save_file[FN_REFLEN]; + bool empty_result= FALSE; MY_INIT(argv[0]); + DBUG_ENTER("main"); save_file[0]= 0; TMPDIR[0]= 0; @@ -7972,8 +8098,8 @@ int main(int argc, char **argv) my_init_dynamic_array(&q_lines, sizeof(struct st_command*), 1024, 1024); - if (hash_init(&var_hash, charset_info, - 1024, 0, 0, get_var_key, var_free, MYF(0))) + if (hash_init2(&var_hash, 64, charset_info, + 128, 0, 0, get_var_key, var_free, MYF(0))) die("Variable hash initialization failed"); var_set_string("MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION); @@ -8000,6 +8126,7 @@ int main(int argc, char **argv) #endif init_dynamic_string(&ds_res, "", 2048, 2048); + init_alloc_root(&require_file_root, 1024, 1024); parse_args(argc, argv); @@ -8058,30 +8185,30 @@ int main(int argc, char **argv) cursor_protocol_enabled= cursor_protocol; st_connection *con= connections; - if (!( mysql_init(&con->mysql))) + if (! (con->mysql= mysql_init(0))) die("Failed in mysql_init()"); if (opt_compress) - mysql_options(&con->mysql,MYSQL_OPT_COMPRESS,NullS); - mysql_options(&con->mysql, MYSQL_OPT_LOCAL_INFILE, 0); - mysql_options(&con->mysql, MYSQL_SET_CHARSET_NAME, + mysql_options(con->mysql,MYSQL_OPT_COMPRESS,NullS); + mysql_options(con->mysql, MYSQL_OPT_LOCAL_INFILE, 0); + mysql_options(con->mysql, MYSQL_SET_CHARSET_NAME, charset_info->csname); if (opt_charsets_dir) - mysql_options(&con->mysql, MYSQL_SET_CHARSET_DIR, + mysql_options(con->mysql, MYSQL_SET_CHARSET_DIR, opt_charsets_dir); if (opt_protocol) - mysql_options(&con->mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); + mysql_options(con->mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); #ifdef HAVE_OPENSSL if (opt_use_ssl) { - mysql_ssl_set(&con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, + mysql_ssl_set(con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); #if MYSQL_VERSION_ID >= 50000 /* Turn on ssl_verify_server_cert only if host is "localhost" */ opt_ssl_verify_server_cert= opt_host && !strcmp(opt_host, "localhost"); - mysql_options(&con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, + mysql_options(con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &opt_ssl_verify_server_cert); #endif } @@ -8089,13 +8216,13 @@ int main(int argc, char **argv) #ifdef HAVE_SMEM if (shared_memory_base_name) - mysql_options(&con->mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); + mysql_options(con->mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); #endif if (!(con->name = my_strdup("default", MYF(MY_WME)))) die("Out of memory"); - safe_connect(&con->mysql, con->name, opt_host, opt_user, opt_pass, + safe_connect(con->mysql, con->name, opt_host, opt_user, opt_pass, opt_db, opt_port, unix_sock); /* Use all time until exit if no explicit 'start_timer' */ @@ -8118,6 +8245,7 @@ int main(int argc, char **argv) verbose_msg("Start processing test commands from '%s' ...", cur_file->file_name); while (!read_command(&command) && !abort_flag) { + my_bool ok_to_do; int current_line_inc = 1, processed = 0; if (command->type == Q_UNKNOWN || command->type == Q_COMMENT_WITH_COMMAND) get_command_type(command); @@ -8134,8 +8262,12 @@ int main(int argc, char **argv) command->abort_on_error= (command->expected_errors.count == 0 && abort_on_error); - /* delimiter needs to be executed so we can continue to parse */ - my_bool ok_to_do= cur_block->ok || command->type == Q_DELIMITER; + /* + some commmands need to be executed or at least parsed unconditionally, + because they change the grammar. + */ + ok_to_do= cur_block->ok || command->type == Q_DELIMITER + || command->type == Q_PERL; /* Some commands need to be "done" the first time if they may get re-iterated over in a true context. This can only happen if there's @@ -8146,8 +8278,7 @@ int main(int argc, char **argv) if (command->type == Q_SOURCE || command->type == Q_ERROR || command->type == Q_WRITE_FILE || - command->type == Q_APPEND_FILE || - command->type == Q_PERL) + command->type == Q_APPEND_FILE) { for (struct st_block *stb= cur_block-1; stb >= block_stack; stb--) { @@ -8177,6 +8308,8 @@ int main(int argc, char **argv) case Q_RPL_PROBE: do_rpl_probe(command); break; case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(command); break; case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(command); break; + case Q_ENABLE_PREPARE_WARNINGS: prepare_warnings_enabled=1; break; + case Q_DISABLE_PREPARE_WARNINGS: prepare_warnings_enabled=0; break; case Q_ENABLE_QUERY_LOG: disable_query_log= 0; var_set_int("$ENABLED_QUERY_LOG", 1); @@ -8322,7 +8455,9 @@ int main(int argc, char **argv) if (save_file[0]) { - strmake(command->require_file, save_file, sizeof(save_file) - 1); + if (!(command->require_file= strdup_root(&require_file_root, + save_file))) + die("out of memory for require_file"); save_file[0]= 0; } run_query(cur_con, command, flags); @@ -8391,12 +8526,12 @@ int main(int argc, char **argv) command->last_argument= command->end; break; case Q_PING: - handle_command_error(command, mysql_ping(&cur_con->mysql)); + handle_command_error(command, mysql_ping(cur_con->mysql), -1); break; case Q_SEND_SHUTDOWN: handle_command_error(command, - mysql_shutdown(&cur_con->mysql, - SHUTDOWN_DEFAULT)); + mysql_shutdown(cur_con->mysql, + SHUTDOWN_DEFAULT), -1); break; case Q_SHUTDOWN_SERVER: do_shutdown_server(command); @@ -8425,10 +8560,10 @@ int main(int argc, char **argv) ps_protocol_enabled= ps_protocol; break; case Q_DISABLE_RECONNECT: - set_reconnect(&cur_con->mysql, 0); + set_reconnect(cur_con->mysql, 0); break; case Q_ENABLE_RECONNECT: - set_reconnect(&cur_con->mysql, 1); + set_reconnect(cur_con->mysql, 1); /* Close any open statements - no reconnect, need new prepare */ close_statements(); break; @@ -8457,7 +8592,10 @@ int main(int argc, char **argv) abort_flag= 1; break; case Q_SKIP: - abort_not_supported_test("%s", command->first_argument); + /* Eval the query, thus replacing all environment variables */ + dynstr_set(&ds_res, 0); + do_eval(&ds_res, command->first_argument, command->end, FALSE); + abort_not_supported_test("%s",ds_res.str); break; case Q_RESULT: @@ -8525,8 +8663,6 @@ int main(int argc, char **argv) if (parsing_disabled) die("Test ended with parsing disabled"); - my_bool empty_result= FALSE; - /* The whole test has been executed _sucessfully_. Time to compare result or save it to record file. @@ -10013,14 +10149,14 @@ void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input) #ifndef HAVE_SETENV static int setenv(const char *name, const char *value, int overwrite) { - size_t buflen= strlen(name) + strlen(value) + 2; - char *envvar= (char *)malloc(buflen); - if(!envvar) - return ENOMEM; - strcpy(envvar, name); - strcat(envvar, "="); - strcat(envvar, value); - putenv(envvar); - return 0; + size_t buflen= strlen(name) + strlen(value) + 2; + char *envvar= (char *)malloc(buflen); + if(!envvar) + return ENOMEM; + strcpy(envvar, name); + strcat(envvar, "="); + strcat(envvar, value); + putenv(envvar); + return 0; } #endif diff --git a/client/readline.cc b/client/readline.cc index 7765a62766f..cb020d62241 100644 --- a/client/readline.cc +++ b/client/readline.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2011, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -33,9 +33,9 @@ static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length); LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file) { LINE_BUFFER *line_buff; - MY_STAT input_file_stat; #ifndef __WIN__ + MY_STAT input_file_stat; if (my_fstat(fileno(file), &input_file_stat, MYF(MY_WME)) || MY_S_ISDIR(input_file_stat.st_mode) || MY_S_ISBLK(input_file_stat.st_mode)) @@ -57,7 +57,8 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file) char *batch_readline(LINE_BUFFER *line_buff) { char *pos; - ulong out_length= 0; + ulong out_length; + LINT_INIT(out_length); if (!(pos=intern_read_line(line_buff, &out_length))) return 0; diff --git a/client/sql_string.cc b/client/sql_string.cc index 4a0f2df927b..d168af1cdf3 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2011, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -124,8 +124,7 @@ bool String::set(double num,uint decimals, CHARSET_INFO *cs) str_charset=cs; if (decimals >= NOT_FIXED_DEC) { - // Enough for a DATETIME - uint32 len= sprintf(buff, "%.15g", num); + uint32 len= my_sprintf(buff,(buff, "%.15g",num));// Enough for a DATETIME return copy(buff, len, &my_charset_latin1, cs, &dummy_errors); } #ifdef HAVE_FCONVERT @@ -680,7 +679,7 @@ void String::qs_append(const char *str, uint32 len) void String::qs_append(double d) { char *buff = Ptr + str_length; - str_length+= sprintf(buff, buff, "%.15g", d); + str_length+= my_sprintf(buff, (buff, "%.15g", d)); } void String::qs_append(double *d) diff --git a/client/sql_string.h b/client/sql_string.h index 57d4d196e8c..6512c4cb4b4 100644 --- a/client/sql_string.h +++ b/client/sql_string.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by |