diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/client_priv.h | 2 | ||||
-rw-r--r-- | client/completion_hash.cc | 2 | ||||
-rw-r--r-- | client/mysql.cc | 97 | ||||
-rw-r--r-- | client/mysql_plugin.c | 17 | ||||
-rw-r--r-- | client/mysql_upgrade.c | 41 | ||||
-rw-r--r-- | client/mysqlbinlog.cc | 240 | ||||
-rw-r--r-- | client/mysqlcheck.c | 27 | ||||
-rw-r--r-- | client/mysqldump.c | 204 | ||||
-rw-r--r-- | client/mysqlimport.c | 2 | ||||
-rw-r--r-- | client/mysqlshow.c | 6 | ||||
-rw-r--r-- | client/mysqlslap.c | 17 | ||||
-rw-r--r-- | client/mysqltest.cc | 155 |
12 files changed, 488 insertions, 322 deletions
diff --git a/client/client_priv.h b/client/client_priv.h index 7c16ca17aab..9fe3b6300f2 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -61,6 +61,7 @@ enum options_client OPT_USE_THREADS, OPT_IMPORT_USE_THREADS, OPT_MYSQL_NUMBER_OF_QUERY, + OPT_IGNORE_DATABASE, OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE, OPT_TZ_UTC, OPT_CREATE_SLAP_SCHEMA, OPT_MYSQLDUMP_SLAVE_APPLY, @@ -98,6 +99,7 @@ enum options_client OPT_REPORT_PROGRESS, OPT_SKIP_ANNOTATE_ROWS_EVENTS, OPT_SSL_CRL, OPT_SSL_CRLPATH, + OPT_PRINT_ROW_COUNT, OPT_PRINT_ROW_EVENT_POSITIONS, OPT_MAX_CLIENT_OPTION /* should be always the last */ }; diff --git a/client/completion_hash.cc b/client/completion_hash.cc index 553d0a1f926..0d88aa9b15e 100644 --- a/client/completion_hash.cc +++ b/client/completion_hash.cc @@ -49,7 +49,7 @@ int completion_hash_init(HashTable *ht, uint nSize) ht->initialized = 0; return FAILURE; } - init_alloc_root(&ht->mem_root, 8192, 0, MYF(0)); + init_alloc_root(&ht->mem_root, "completion_hash", 8192, 0, MYF(0)); ht->pHashFunction = hashpjw; ht->nTableSize = nSize; ht->initialized = 1; diff --git a/client/mysql.cc b/client/mysql.cc index d672473798e..d5ab1a12c7a 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2018, Oracle and/or its affiliates. - Copyright (c) 2009, 2018, MariaDB Corporation + Copyright (c) 2009, 2019, MariaDB Corporation. 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 @@ -41,7 +41,7 @@ #include <signal.h> #include <violite.h> #include <my_sys.h> - +#include <source_revision.h> #if defined(USE_LIBEDIT_INTERFACE) && defined(HAVE_LOCALE_H) #include <locale.h> #endif @@ -1060,13 +1060,13 @@ extern "C" int write_history(const char *command); extern "C" HIST_ENTRY *history_get(int num); extern "C" int history_length; static int not_in_history(const char *line); -static void initialize_readline (char *name); +static void initialize_readline (); static void fix_history(String *final_command); #endif static COMMANDS *find_command(char *name); static COMMANDS *find_command(char cmd_name); -static bool add_line(String &, char *, ulong, char *, bool *, bool); +static bool add_line(String &, char *, size_t line_length, char *, bool *, bool); static void remove_cntrl(String &buffer); static void print_table_data(MYSQL_RES *result); static void print_table_data_html(MYSQL_RES *result); @@ -1074,9 +1074,7 @@ static void print_table_data_xml(MYSQL_RES *result); static void print_tab_data(MYSQL_RES *result); static void print_table_data_vertically(MYSQL_RES *result); static void print_warnings(void); -static ulong start_timer(void); -static void end_timer(ulong start_time,char *buff); -static void mysql_end_timer(ulong start_time,char *buff); +static void end_timer(ulonglong start_time, char *buff); static void nice_time(double sec,char *buff,bool part_second); extern "C" sig_handler mysql_end(int sig) __attribute__ ((noreturn)); extern "C" sig_handler handle_sigint(int sig); @@ -1206,7 +1204,7 @@ int main(int argc,char *argv[]) sf_leaking_memory= 0; glob_buffer.realloc(512); completion_hash_init(&ht, 128); - init_alloc_root(&hash_mem_root, 16384, 0, MYF(0)); + init_alloc_root(&hash_mem_root, "hash", 16384, 0, MYF(0)); if (sql_connect(current_host,current_db,current_user,opt_password, opt_silent)) { @@ -1243,7 +1241,7 @@ int main(int argc,char *argv[]) } #ifdef HAVE_READLINE - initialize_readline((char*) my_progname); + initialize_readline(); if (!status.batch && !quick && !opt_html && !opt_xml) { /* read-history from file, default ~/.mysql_history*/ @@ -1710,19 +1708,18 @@ static struct my_option my_long_options[] = static void usage(int version) { +#ifdef HAVE_READLINE #if defined(USE_LIBEDIT_INTERFACE) const char* readline= ""; #else const char* readline= "readline"; #endif - -#ifdef HAVE_READLINE printf("%s Ver %s Distrib %s, for %s (%s) using %s %s\n", my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE, readline, rl_library_version); #else - printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, VER, - MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); + printf("%s Ver %s Distrib %s, for %s (%s), source revision %s\n", my_progname, VER, + MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,SOURCE_REVISION); #endif if (version) @@ -1987,7 +1984,7 @@ static int read_and_execute(bool interactive) ulong line_number=0; bool ml_comment= 0; COMMANDS *com; - ulong line_length= 0; + size_t line_length= 0; status.exit_status=1; real_binary_mode= !interactive && opt_binary_mode; @@ -2281,7 +2278,7 @@ static COMMANDS *find_command(char *name) } -static bool add_line(String &buffer, char *line, ulong line_length, +static bool add_line(String &buffer, char *line, size_t line_length, char *in_string, bool *ml_comment, bool truncated) { uchar inchar; @@ -2671,10 +2668,11 @@ static int fake_magic_space(const char *, int) } -static void initialize_readline (char *name) +static void initialize_readline () { /* Allow conditional parsing of the ~/.inputrc file. */ - rl_readline_name = name; + rl_readline_name= (char *) "mysql"; + rl_terminal_name= getenv("TERM"); /* Tell the completer that we want a crack first. */ #if defined(USE_NEW_READLINE_INTERFACE) @@ -2989,12 +2987,12 @@ static void get_current_db() The different commands ***************************************************************************/ -int mysql_real_query_for_lazy(const char *buf, int length) +int mysql_real_query_for_lazy(const char *buf, size_t length) { for (uint retry=0;; retry++) { int error; - if (!mysql_real_query(&mysql,buf,length)) + if (!mysql_real_query(&mysql,buf,(ulong)length)) return 0; error= put_error(&mysql); if (mysql_errno(&mysql) != CR_SERVER_GONE_ERROR || retry > 1 || @@ -3213,9 +3211,10 @@ static int com_go(String *buffer,char *line __attribute__((unused))) { char buff[200]; /* about 110 chars used so far */ - char time_buff[52+3+1]; /* time max + space & parens + NUL */ + char time_buff[53+3+1]; /* time max + space & parens + NUL */ MYSQL_RES *result; - ulong timer, warnings= 0; + ulonglong timer; + ulong warnings= 0; uint error= 0; int err= 0; @@ -3254,7 +3253,7 @@ com_go(String *buffer,char *line __attribute__((unused))) return 0; } - timer=start_timer(); + timer= microsecond_interval_timer(); executing_query= 1; error= mysql_real_query_for_lazy(buffer->ptr(),buffer->length()); report_progress_end(); @@ -3293,7 +3292,7 @@ com_go(String *buffer,char *line __attribute__((unused))) } if (verbose >= 3 || !opt_silent) - mysql_end_timer(timer,time_buff); + end_timer(timer, time_buff); else time_buff[0]= '\0'; @@ -3564,10 +3563,10 @@ is_binary_field(MYSQL_FIELD *field) /* Print binary value as hex literal (0x ...) */ static void -print_as_hex(FILE *output_file, const char *str, ulong len, ulong total_bytes_to_send) +print_as_hex(FILE *output_file, const char *str, size_t len, size_t total_bytes_to_send) { const char *ptr= str, *end= ptr+len; - ulong i; + size_t i; fprintf(output_file, "0x"); for(; ptr < end; ptr++) fprintf(output_file, "%02X", *((uchar*)ptr)); @@ -3617,11 +3616,11 @@ print_table_data(MYSQL_RES *result) (void) tee_fputs("|", PAGER); for (uint off=0; (field = mysql_fetch_field(result)) ; off++) { - uint name_length= (uint) strlen(field->name); - uint numcells= charset_info->cset->numcells(charset_info, + size_t name_length= (uint) strlen(field->name); + size_t numcells= charset_info->cset->numcells(charset_info, field->name, field->name + name_length); - uint display_length= field->max_length + name_length - numcells; + size_t display_length= field->max_length + name_length - numcells; tee_fprintf(PAGER, " %-*s |",(int) MY_MIN(display_length, MAX_COLUMN_LENGTH), field->name); @@ -3642,7 +3641,6 @@ print_table_data(MYSQL_RES *result) const char *buffer; uint data_length; uint field_max_length; - uint visible_length; uint extra_padding; if (off) @@ -3670,7 +3668,7 @@ print_table_data(MYSQL_RES *result) We need to find how much screen real-estate we will occupy to know how many extra padding-characters we should send with the printing function. */ - visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length); + size_t visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length); extra_padding= (uint) (data_length - visible_length); if (opt_binhex && is_binary_field(field)) @@ -4210,8 +4208,7 @@ com_edit(String *buffer,char *line __attribute__((unused))) const char *editor; MY_STAT stat_arg; - if ((fd=create_temp_file(filename,NullS,"sql", O_CREAT | O_WRONLY, - MYF(MY_WME))) < 0) + if ((fd= create_temp_file(filename,NullS,"sql", 0, MYF(MY_WME))) < 0) goto err; if (buffer->is_empty() && !old_buffer.is_empty()) (void) my_write(fd,(uchar*) old_buffer.ptr(),old_buffer.length(), @@ -5094,31 +5091,11 @@ void tee_putc(int c, FILE *file) putc(c, OUTFILE); } -#if defined(__WIN__) -#include <time.h> -#else -#include <sys/times.h> -#ifdef _SC_CLK_TCK // For mit-pthreads -#undef CLOCKS_PER_SEC -#define CLOCKS_PER_SEC (sysconf(_SC_CLK_TCK)) -#endif -#endif - -static ulong start_timer(void) -{ -#if defined(__WIN__) - return clock(); -#else - struct tms tms_tmp; - return times(&tms_tmp); -#endif -} - /** Write as many as 52+1 bytes to buff, in the form of a legible duration of time. - len("4294967296 days, 23 hours, 59 minutes, 60.00 seconds") -> 52 + len("4294967296 days, 23 hours, 59 minutes, 60.000 seconds") -> 53 */ static void nice_time(double sec,char *buff,bool part_second) { @@ -5145,24 +5122,20 @@ static void nice_time(double sec,char *buff,bool part_second) buff=strmov(buff," min "); } if (part_second) - sprintf(buff,"%.2f sec",sec); + sprintf(buff,"%.3f sec",sec); else sprintf(buff,"%d sec",(int) sec); } -static void end_timer(ulong start_time,char *buff) +static void end_timer(ulonglong start_time, char *buff) { - nice_time((double) (start_timer() - start_time) / - CLOCKS_PER_SEC,buff,1); -} + double sec; - -static void mysql_end_timer(ulong start_time,char *buff) -{ buff[0]=' '; buff[1]='('; - end_timer(start_time,buff+2); + sec= (microsecond_interval_timer() - start_time) / (double) (1000 * 1000); + nice_time(sec, buff + 2, 1); strmov(strend(buff),")"); } diff --git a/client/mysql_plugin.c b/client/mysql_plugin.c index 58b1608c560..8e5897b4b86 100644 --- a/client/mysql_plugin.c +++ b/client/mysql_plugin.c @@ -159,8 +159,7 @@ static int make_tempfile(char *filename, const char *ext) { int fd= 0; - if ((fd=create_temp_file(filename, NullS, ext, O_CREAT | O_WRONLY, - MYF(MY_WME))) < 0) + if ((fd= create_temp_file(filename, NullS, ext, 0, MYF(MY_WME))) < 0) { fprintf(stderr, "ERROR: Cannot generate temporary file. Error code: %d.\n", fd); @@ -262,7 +261,7 @@ static char *convert_path(const char *argument) /* Convert / to \\ to make Windows paths */ char *winfilename= my_strdup(argument, MYF(MY_FAE)); char *pos, *end; - int length= strlen(argument); + size_t length= strlen(argument); for (pos= winfilename, end= pos+length ; pos < end ; pos++) { @@ -365,6 +364,12 @@ static int get_default_values() } /* Now open the file and read the defaults we want. */ file= fopen(defaults_file, "r"); + if (file == NULL) + { + fprintf(stderr, "ERROR: failed to open file %s: %s.\n", defaults_file, + strerror(errno)); + goto exit; + } while (fgets(line, FN_REFLEN, file) != NULL) { char *value= 0; @@ -712,11 +717,11 @@ static int check_options(int argc, char **argv, char *operation) /* Form prefix strings for the options. */ const char *basedir_prefix = "--basedir="; - int basedir_len= strlen(basedir_prefix); + size_t basedir_len= strlen(basedir_prefix); const char *datadir_prefix = "--datadir="; - int datadir_len= strlen(datadir_prefix); + size_t datadir_len= strlen(datadir_prefix); const char *plugin_dir_prefix = "--plugin_dir="; - int plugin_dir_len= strlen(plugin_dir_prefix); + size_t plugin_dir_len= strlen(plugin_dir_prefix); strcpy(plugin_name, ""); for (i = 0; i < argc && num_found < 5; i++) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 835dd9fd00d..bba2530f266 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -558,8 +558,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res, DBUG_PRINT("enter", ("query: %s", query)); if ((fd= create_temp_file(query_file_path, opt_tmpdir[0] ? opt_tmpdir : NULL, - "sql", O_CREAT | O_SHARE | O_RDWR, - MYF(MY_WME))) < 0) + "sql", O_SHARE, MYF(MY_WME))) < 0) die("Failed to create temporary file for defaults"); /* @@ -673,7 +672,7 @@ static int get_upgrade_info_file_name(char* name) */ -static int upgrade_already_done(void) +static int upgrade_already_done(myf flags) { FILE *in; char upgrade_info_file[FN_REFLEN]= {0}; @@ -681,17 +680,23 @@ static int upgrade_already_done(void) if (get_upgrade_info_file_name(upgrade_info_file)) return 0; /* Could not get filename => not sure */ - if (!(in= my_fopen(upgrade_info_file, O_RDONLY, MYF(0)))) + if (!(in= my_fopen(upgrade_info_file, O_RDONLY, flags))) return 0; /* Could not open file => not sure */ bzero(upgrade_from_version, sizeof(upgrade_from_version)); if (!fgets(upgrade_from_version, sizeof(upgrade_from_version), in)) { - /* Ignore, will be detected by strncmp() below */ + /* Preserve errno for caller */ + int save_errno= errno; + (void) my_fclose(in, flags); + errno= save_errno; + return 0; } - my_fclose(in, MYF(0)); + if (my_fclose(in, flags)) + return 0; + errno= 0; return (strncmp(upgrade_from_version, MYSQL_SERVER_VERSION, sizeof(MYSQL_SERVER_VERSION)-1)==0); } @@ -720,23 +725,24 @@ static void create_mysql_upgrade_info_file(void) { fprintf(stderr, "Could not create the upgrade info file '%s' in " - "the MySQL Servers datadir, errno: %d\n", + "the MariaDB Servers datadir, errno: %d\n", upgrade_info_file, errno); return; } /* Write new version to file */ - fputs(MYSQL_SERVER_VERSION, out); - my_fclose(out, MYF(0)); + my_fwrite(out, (uchar*) MYSQL_SERVER_VERSION, + sizeof(MYSQL_SERVER_VERSION), MY_WME); + my_fclose(out, MYF(MY_WME)); /* Check if the upgrad_info_file was properly created/updated It's not a fatal error -> just print a message if it fails */ - if (!upgrade_already_done()) + if (!upgrade_already_done(MY_WME)) fprintf(stderr, - "Could not write to the upgrade info file '%s' in " - "the MySQL Servers datadir, errno: %d\n", + "Upgrade file '%s' was not properly created. " + "Got error errno while checking file content: %d\n", upgrade_info_file, errno); return; } @@ -958,8 +964,9 @@ static int install_used_engines(void) { char buf[512]; DYNAMIC_STRING ds_result; - const char *query = "SELECT DISTINCT LOWER(engine) FROM information_schema.tables" - " WHERE table_comment LIKE 'Unknown storage engine%'"; + const char *query = "SELECT DISTINCT LOWER(engine) AS c1 FROM information_schema.tables" + " WHERE table_comment LIKE 'Unknown storage engine%'" + " ORDER BY c1"; if (opt_systables_only || !from_before_10_1()) { @@ -1136,7 +1143,7 @@ int main(int argc, char **argv) load_defaults_or_exit("my", load_default_groups, &argc, &argv); defaults_argv= argv; /* Must be freed by 'free_defaults' */ -#if __WIN__ +#if defined(__WIN__) if (GetModuleFileName(NULL, self_name, FN_REFLEN) == 0) #endif { @@ -1168,7 +1175,7 @@ int main(int argc, char **argv) cnf_file_path= strmov(defaults_file, "--defaults-file="); { int fd= create_temp_file(cnf_file_path, opt_tmpdir[0] ? opt_tmpdir : NULL, - "mysql_upgrade-", O_CREAT | O_WRONLY, MYF(MY_FAE)); + "mysql_upgrade-", 0, MYF(MY_FAE)); if (fd < 0) die(NULL); my_write(fd, USTRING_WITH_LEN( "[client]\n"), MYF(MY_FAE)); @@ -1189,7 +1196,7 @@ int main(int argc, char **argv) Read the mysql_upgrade_info file to check if mysql_upgrade already has been run for this installation of MySQL */ - if (!opt_force && upgrade_already_done()) + if (!opt_force && upgrade_already_done(0)) { printf("This installation of MySQL is already upgraded to %s, " "use --force if you still need to run mysql_upgrade\n", diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index acccf0a3411..0e296a358e1 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2014, Oracle and/or its affiliates. - Copyright (c) 2009, 2014, MariaDB + Copyright (c) 2009, 2019, MariaDB 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 @@ -32,7 +32,10 @@ #define MYSQL_CLIENT #undef MYSQL_SERVER #define TABLE TABLE_CLIENT +/* This hack is here to avoid adding COMPRESSED data types to libmariadb. */ +#define MYSQL_TYPE_TIME2 MYSQL_TYPE_TIME2,MYSQL_TYPE_BLOB_COMPRESSED=140,MYSQL_TYPE_VARCHAR_COMPRESSED=141 #include "client_priv.h" +#undef MYSQL_TYPE_TIME2 #include <my_time.h> #include <sslopt-vars.h> /* That one is necessary for defines of OPTION_NO_FOREIGN_KEY_CHECKS etc */ @@ -87,7 +90,8 @@ static char *result_file_name= 0; static const char *output_prefix= ""; #ifndef DBUG_OFF -static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace"; +static const char *default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace"; +const char *current_dbug_option= default_dbug_option; #endif static const char *load_groups[]= { "mysqlbinlog", "client", "client-server", "client-mariadb", 0 }; @@ -107,6 +111,8 @@ static char *opt_base64_output_mode_str= NullS; static char* database= 0; static char* table= 0; static my_bool force_opt= 0, short_form= 0, remote_opt= 0; +static my_bool print_row_count= 0, print_row_event_positions= 0; +static my_bool print_row_count_used= 0, print_row_event_positions_used= 0; static my_bool debug_info_flag, debug_check_flag; static my_bool force_if_open_opt= 1; static my_bool opt_raw_mode= 0, opt_stop_never= 0; @@ -222,13 +228,15 @@ void keep_annotate_event(Annotate_rows_log_event* event) annotate_event= event; } -void print_annotate_event(PRINT_EVENT_INFO *print_event_info) +bool print_annotate_event(PRINT_EVENT_INFO *print_event_info) { + bool error= 0; if (annotate_event) { annotate_event->print(result_file, print_event_info); free_annotate_event(); } + return error; } static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *, const char*); @@ -431,7 +439,7 @@ File Load_log_processor::prepare_new_file_for_old_format(Load_log_event *le, return -1; } - le->set_fname_outside_temp_buf(filename,len+(uint) strlen(tail)); + le->set_fname_outside_temp_buf(filename,len+strlen(tail)); return file; } @@ -529,7 +537,7 @@ Exit_status Load_log_processor::process_first_event(const char *bname, uint file_id, Create_file_log_event *ce) { - uint full_len= target_dir_name_len + blen + 9 + 9 + 1; + size_t full_len= target_dir_name_len + blen + 9 + 9 + 1; Exit_status retval= OK_CONTINUE; char *fname, *ptr; File file; @@ -575,7 +583,7 @@ Exit_status Load_log_processor::process_first_event(const char *bname, } if (ce) - ce->set_fname_outside_temp_buf(fname, (uint) strlen(fname)); + ce->set_fname_outside_temp_buf(fname, strlen(fname)); if (my_write(file, (uchar*)block, block_len, MYF(MY_WME|MY_NABP))) { @@ -792,7 +800,7 @@ print_use_stmt(PRINT_EVENT_INFO* pinfo, const Query_log_event *ev) static void print_skip_replication_statement(PRINT_EVENT_INFO *pinfo, const Log_event *ev) { - int cur_val; + bool cur_val; cur_val= (ev->flags & LOG_EVENT_SKIP_REPLICATION_F) != 0; if (cur_val == pinfo->skip_replication) @@ -844,13 +852,15 @@ write_event_header_and_base64(Log_event *ev, FILE *result_file, DBUG_ENTER("write_event_header_and_base64"); /* Write header and base64 output to cache */ - ev->print_header(head, print_event_info, FALSE); + if (ev->print_header(head, print_event_info, FALSE)) + DBUG_RETURN(ERROR_STOP); DBUG_ASSERT(print_event_info->base64_output_mode == BASE64_OUTPUT_ALWAYS); - ev->print_base64(body, print_event_info, - print_event_info->base64_output_mode != - BASE64_OUTPUT_DECODE_ROWS); + if (ev->print_base64(body, print_event_info, + print_event_info->base64_output_mode != + BASE64_OUTPUT_DECODE_ROWS)) + DBUG_RETURN(ERROR_STOP); /* Read data from cache and write to result file */ if (copy_event_cache_to_file_and_reinit(head, result_file) || @@ -872,26 +882,21 @@ static bool print_base64(PRINT_EVENT_INFO *print_event_info, Log_event *ev) passed --short-form, because --short-form disables printing row events. */ + if (!print_event_info->printed_fd_event && !short_form && - opt_base64_output_mode != BASE64_OUTPUT_DECODE_ROWS) + opt_base64_output_mode != BASE64_OUTPUT_DECODE_ROWS && + opt_base64_output_mode != BASE64_OUTPUT_NEVER) { const char* type_str= ev->get_type_str(); - if (opt_base64_output_mode == BASE64_OUTPUT_NEVER) - error("--base64-output=never specified, but binlog contains a " - "%s event which must be printed in base64.", - type_str); - else - error("malformed binlog: it does not contain any " - "Format_description_log_event. I now found a %s event, which " + error("malformed binlog: it does not contain any " + "Format_description_log_event. Found a %s event, which " "is not safe to process without a " "Format_description_log_event.", type_str); return 1; } - ev->print(result_file, print_event_info); - return - print_event_info->head_cache.error == -1 || - print_event_info->body_cache.error == -1; + + return ev->print(result_file, print_event_info); } @@ -901,6 +906,8 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, Table_map_log_event *ignored_map= print_event_info->m_table_map_ignored.get_table(table_id); bool skip_event= (ignored_map != NULL); + char ll_buff[21]; + bool result= 0; if (opt_flashback) { @@ -973,19 +980,18 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, return 0; if (!opt_flashback) - return print_base64(print_event_info, ev); + result= print_base64(print_event_info, ev); else { if (is_stmt_end) { - bool res= false; Log_event *e= NULL; // Print the row_event from the last one to the first one for (uint i= events_in_stmt.elements; i > 0; --i) { e= *(dynamic_element(&events_in_stmt, i - 1, Log_event**)); - res= res || print_base64(print_event_info, e); + result= result || print_base64(print_event_info, e); } // Copy all output into the Log_event ev->output_buf.copy(e->output_buf); @@ -996,12 +1002,17 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, delete e; } reset_dynamic(&events_in_stmt); - - return res; } } - return 0; + if (is_stmt_end && !result) + { + if (print_event_info->print_row_count) + fprintf(result_file, "# Number of rows: %s\n", + llstr(print_event_info->row_events, ll_buff)); + print_event_info->row_events= 0; + } + return result; } @@ -1032,7 +1043,6 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, Log_event_type ev_type= ev->get_type_code(); my_bool destroy_evt= TRUE; DBUG_ENTER("process_event"); - print_event_info->short_form= short_form; Exit_status retval= OK_CONTINUE; IO_CACHE *const head= &print_event_info->head_cache; @@ -1078,7 +1088,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, retval= OK_STOP; goto end; } - if (!short_form && !opt_flashback) + if (print_row_event_positions) fprintf(result_file, "# at %s\n",llstr(pos,ll_buff)); if (!opt_hexdump) @@ -1119,7 +1129,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, else { print_skip_replication_statement(print_event_info, ev); - ev->print(result_file, print_event_info); + if (ev->print(result_file, print_event_info)) + goto err; } if (head->error == -1) goto err; @@ -1154,8 +1165,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, else { print_skip_replication_statement(print_event_info, ev); - ce->print(result_file, print_event_info, TRUE); - if (head->error == -1) + if (ce->print(result_file, print_event_info, TRUE)) goto err; } // If this binlog is not 3.23 ; why this test?? @@ -1178,8 +1188,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, the subsequent call load_processor.process fails, because the output of Append_block_log_event::print is only a comment. */ - ev->print(result_file, print_event_info); - if (head->error == -1) + if (ev->print(result_file, print_event_info)) goto err; if ((retval= load_processor.process((Append_block_log_event*) ev)) != OK_CONTINUE) @@ -1188,8 +1197,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, case EXEC_LOAD_EVENT: { - ev->print(result_file, print_event_info); - if (head->error == -1) + if (ev->print(result_file, print_event_info)) goto err; Execute_load_log_event *exv= (Execute_load_log_event*)ev; Create_file_log_event *ce= load_processor.grab_event(exv->file_id); @@ -1200,15 +1208,16 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, */ if (ce) { + bool error; /* We must not convert earlier, since the file is used by my_open() in Load_log_processor::append(). */ convert_path_to_forward_slashes((char*) ce->fname); - ce->print(result_file, print_event_info, TRUE); + error= ce->print(result_file, print_event_info, TRUE); my_free((void*)ce->fname); delete ce; - if (head->error == -1) + if (error) goto err; } else @@ -1219,10 +1228,10 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, case FORMAT_DESCRIPTION_EVENT: delete glob_description_event; glob_description_event= (Format_description_log_event*) ev; + destroy_evt= 0; print_event_info->common_header_len= glob_description_event->common_header_len; - ev->print(result_file, print_event_info); - if (head->error == -1) + if (ev->print(result_file, print_event_info)) goto err; if (!remote_opt) { @@ -1252,8 +1261,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, } break; case BEGIN_LOAD_QUERY_EVENT: - ev->print(result_file, print_event_info); - if (head->error == -1) + if (ev->print(result_file, print_event_info)) goto err; if ((retval= load_processor.process((Begin_load_query_log_event*) ev)) != OK_CONTINUE) @@ -1271,11 +1279,9 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, { convert_path_to_forward_slashes(fname); print_skip_replication_statement(print_event_info, ev); - exlq->print(result_file, print_event_info, fname); - if (head->error == -1) + if (exlq->print(result_file, print_event_info, fname)) { - if (fname) - my_free(fname); + my_free(fname); goto err; } } @@ -1283,9 +1289,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, warning("Ignoring Execute_load_query since there is no " "Begin_load_query event for file_id: %u", exlq->file_id); } - - if (fname) - my_free(fname); + my_free(fname); break; } case ANNOTATE_ROWS_EVENT: @@ -1431,7 +1435,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, print the kept Annotate event (if there is any). print_annotate_event() also deletes the kept Annotate event. */ - print_annotate_event(print_event_info); + if (print_annotate_event(print_event_info)) + goto err; size_t len_to= 0; const char* db_to= binlog_filter->get_rewrite_db(map->get_db_name(), &len_to); @@ -1461,10 +1466,18 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, { Rows_log_event *e= (Rows_log_event*) ev; bool is_stmt_end= e->get_flags(Rows_log_event::STMT_END_F); + if (!print_event_info->found_row_event) + { + print_event_info->found_row_event= 1; + print_event_info->row_events= 0; + } if (print_row_event(print_event_info, ev, e->get_table_id(), e->get_flags(Rows_log_event::STMT_END_F))) goto err; - if (opt_flashback && !is_stmt_end) + DBUG_PRINT("info", ("is_stmt_end: %d", (int) is_stmt_end)); + if (is_stmt_end) + print_event_info->found_row_event= 0; + else if (opt_flashback) destroy_evt= FALSE; break; } @@ -1477,7 +1490,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, if (print_row_event(print_event_info, ev, e->get_table_id(), e->get_flags(Old_rows_log_event::STMT_END_F))) goto err; - if (opt_flashback && !is_stmt_end) + DBUG_PRINT("info", ("is_stmt_end: %d", (int) is_stmt_end)); + if (!is_stmt_end && opt_flashback) destroy_evt= FALSE; break; } @@ -1486,8 +1500,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, /* fall through */ default: print_skip_replication_statement(print_event_info, ev); - ev->print(result_file, print_event_info); - if (head->error == -1) + if (ev->print(result_file, print_event_info)) goto err; } } @@ -1498,7 +1511,8 @@ err: retval= ERROR_STOP; end: rec_count++; - + + DBUG_PRINT("info", ("end event processing")); /* Destroy the log_event object. MariaDB MWL#36: mainline does this: @@ -1542,6 +1556,7 @@ end: if (destroy_evt) /* destroy it later if not set (ignored table map) */ delete ev; } + DBUG_PRINT("exit",("return: %d", retval)); DBUG_RETURN(retval); } @@ -1553,14 +1568,15 @@ static struct my_option my_options[] = {"base64-output", OPT_BASE64_OUTPUT_MODE, /* 'unspec' is not mentioned because it is just a placeholder. */ "Determine when the output statements should be base64-encoded BINLOG " - "statements: 'never' disables it and works only for binlogs without " - "row-based events; 'decode-rows' decodes row events into commented SQL " - "statements if the --verbose option is also given; 'auto' prints base64 " - "only when necessary (i.e., for row-based events and format description " - "events); 'always' prints base64 whenever possible. 'always' is " - "deprecated, will be removed in a future version, and should not be used " - "in a production system. --base64-output with no 'name' argument is " - "equivalent to --base64-output=always and is also deprecated. If no " + "statements: 'never' doesn't print binlog row events and should not be " + "used when directing output to a MariaDB master; " + "'decode-rows' decodes row events into commented SQL statements if the " + "--verbose option is also given; " + "'auto' prints base64 only when necessary (i.e., for row-based events and " + "format description events); " + "'always' prints base64 whenever possible. " + "--base64-output with no 'name' argument is equivalent to " + "--base64-output=always and is also deprecated. If no " "--base64-output[=name] option is given at all, the default is 'auto'.", &opt_base64_output_mode_str, &opt_base64_output_mode_str, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, @@ -1577,8 +1593,8 @@ static struct my_option my_options[] = &database, &database, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifndef DBUG_OFF - {"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.", ¤t_dbug_option, + ¤t_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, @@ -1660,6 +1676,14 @@ static struct my_option my_options[] = &flashback_review_tablename, &flashback_review_tablename, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif + {"print-row-count", OPT_PRINT_ROW_COUNT, + "Print row counts for each row events", + &print_row_count, &print_row_count, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, + 0, 0}, + {"print-row-event-positions", OPT_PRINT_ROW_EVENT_POSITIONS, + "Print row event positions", + &print_row_event_positions, &print_row_event_positions, 0, GET_BOOL, + NO_ARG, 1, 0, 0, 0, 0, 0}, {"server-id", 0, "Extract only binlog entries created by the server having the given id.", &server_id, &server_id, 0, GET_ULONG, @@ -1673,10 +1697,11 @@ static struct my_option my_options[] = &shared_memory_base_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"short-form", 's', "Just show regular queries: no extra info and no " - "row-based events. This is for testing only, and should not be used in " - "production systems. If you want to suppress base64-output, consider " - "using --base64-output=never instead.", + {"short-form", 's', "Just show regular queries: no extra info, no " + "row-based events and no row counts. This is mainly for testing only, " + "and should not be used to feed to the MariaDB server. " + "If you want to just suppress base64-output, you can instead " + "use --base64-output=never", &short_form, &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"socket", 'S', "The socket file to use for connection.", @@ -1787,9 +1812,12 @@ Example: rewrite-db='from->to'.", */ static void error_or_warning(const char *format, va_list args, const char *msg) { + if (result_file) + fflush(result_file); fprintf(stderr, "%s: ", msg); vfprintf(stderr, format, args); fprintf(stderr, "\n"); + fflush(stderr); } /** @@ -1842,6 +1870,7 @@ static void warning(const char *format,...) */ static void cleanup() { + DBUG_ENTER("cleanup"); my_free(pass); my_free(database); my_free(table); @@ -1855,12 +1884,13 @@ static void cleanup() delete glob_description_event; if (mysql) mysql_close(mysql); + DBUG_VOID_RETURN; } static void print_version() { - printf("%s Ver 3.3 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE); + printf("%s Ver 3.4 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE); } @@ -1911,7 +1941,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), switch (optid) { #ifndef DBUG_OFF case '#': - DBUG_PUSH(argument ? argument : default_dbug_option); + if (!argument) + argument= (char*) default_dbug_option; + current_dbug_option= argument; + DBUG_PUSH(argument); break; #endif #include <sslopt-case.h> @@ -2024,6 +2057,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), binlog_filter->add_db_rewrite(key, val); break; } + case OPT_PRINT_ROW_COUNT: + print_row_count_used= 1; + break; + case OPT_PRINT_ROW_EVENT_POSITIONS: + print_row_event_positions_used= 1; + break; case 'v': if (argument == disabled_my_option) verbose= 0; @@ -2156,11 +2195,30 @@ static Exit_status dump_log_entries(const char* logname) fprintf(result_file, "DELIMITER /*!*/;\n"); strmov(print_event_info.delimiter, "/*!*/;"); - print_event_info.verbose= short_form ? 0 : verbose; + if (short_form) + { + if (!print_row_event_positions_used) + print_row_event_positions= 0; + if (!print_row_count_used) + print_row_count = 0; + } + if (opt_flashback) + { + if (!print_row_event_positions_used) + print_row_event_positions= 0; + } + print_event_info.verbose= short_form ? 0 : verbose; + print_event_info.short_form= short_form; + print_event_info.print_row_count= print_row_count; + print_event_info.file= result_file; + fflush(result_file); rc= (remote_opt ? dump_remote_log_entries(&print_event_info, logname) : dump_local_log_entries(&print_event_info, logname)); + if (rc == ERROR_STOP) + return rc; + /* Set delimiter back to semicolon */ if (!opt_raw_mode && !opt_flashback) fprintf(result_file, "DELIMITER ;\n"); @@ -2231,6 +2289,8 @@ static Exit_status check_master_version() } delete glob_description_event; + glob_description_event= NULL; + switch (version) { case 3: glob_description_event= new Format_description_log_event(1); @@ -2249,7 +2309,6 @@ static Exit_status check_master_version() glob_description_event= new Format_description_log_event(3); break; default: - glob_description_event= NULL; error("Could not find server version: " "Master reported unrecognized MySQL version '%s'.", row[0]); goto err; @@ -2490,6 +2549,7 @@ static Exit_status handle_event_raw_mode(PRINT_EVENT_INFO *print_event_info, error("Could not write into log file '%s'", out_file_name); DBUG_RETURN(ERROR_STOP); } + print_event_info->file= result_file; delete glob_description_event; glob_description_event= (Format_description_log_event*) ev; @@ -2759,7 +2819,7 @@ static Exit_status check_header(IO_CACHE* file, Format_description_log_event *new_description_event; my_b_seek(file, tmp_pos); /* seek back to event's start */ if (!(new_description_event= (Format_description_log_event*) - Log_event::read_log_event(file, 0, glob_description_event, + Log_event::read_log_event(file, glob_description_event, opt_verify_binlog_checksum))) /* EOF can't be hit here normally, so it's a real error */ { @@ -2793,7 +2853,7 @@ static Exit_status check_header(IO_CACHE* file, { Log_event *ev; my_b_seek(file, tmp_pos); /* seek back to event's start */ - if (!(ev= Log_event::read_log_event(file, 0, glob_description_event, + if (!(ev= Log_event::read_log_event(file, glob_description_event, opt_verify_binlog_checksum))) { /* EOF can't be hit here normally, so it's a real error */ @@ -2859,7 +2919,7 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, stdin in binary mode. Errors on setting this mode result in halting the function and printing an error message to stderr. */ -#if defined (__WIN__) || (_WIN64) +#if defined (__WIN__) || defined(_WIN64) if (_setmode(fileno(stdin), O_BINARY) == -1) { error("Could not set binary mode on stdin."); @@ -2907,7 +2967,7 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, char llbuff[21]; my_off_t old_off = my_b_tell(file); - Log_event* ev = Log_event::read_log_event(file, 0, glob_description_event, + Log_event* ev = Log_event::read_log_event(file, glob_description_event, opt_verify_binlog_checksum); if (!ev) { @@ -2986,13 +3046,6 @@ int main(int argc, char** argv) if (opt_base64_output_mode == BASE64_OUTPUT_UNSPEC) opt_base64_output_mode= BASE64_OUTPUT_AUTO; - if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) - warning("The --base64-output=always flag and the --base64-output flag " - "(with '=MODE' omitted), are deprecated. " - "The output generated when these flags are used cannot be " - "parsed by mysql 5.6.0 and later. " - "The flags will be removed in a future version. " - "Please use --base64-output=auto instead."); my_set_max_open_files(open_files_limit); @@ -3105,7 +3158,7 @@ int main(int argc, char** argv) If enable flashback, need to print the events from the end to the beginning */ - if (opt_flashback) + if (opt_flashback && retval != ERROR_STOP) { for (uint i= binlog_events.elements; i > 0; --i) { @@ -3120,12 +3173,15 @@ int main(int argc, char** argv) } /* Set delimiter back to semicolon */ - if (!stop_event_string.is_empty()) - fprintf(result_file, "%s", stop_event_string.ptr()); - if (!opt_raw_mode && opt_flashback) - fprintf(result_file, "DELIMITER ;\n"); + if (retval != ERROR_STOP) + { + if (!stop_event_string.is_empty()) + fprintf(result_file, "%s", stop_event_string.ptr()); + if (!opt_raw_mode && opt_flashback) + fprintf(result_file, "DELIMITER ;\n"); + } - if (!opt_raw_mode) + if (retval != ERROR_STOP && !opt_raw_mode) { /* Issue a ROLLBACK in case the last printed binlog was crashed and had half diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 42c4cae5621..aaf77dbb743 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -543,7 +543,7 @@ static int process_selected_tables(char *db, char **table_names, int tables) { int view; char *table; - uint table_len; + size_t table_len; DBUG_ENTER("process_selected_tables"); if (use_db(db)) @@ -587,6 +587,7 @@ static int process_selected_tables(char *db, char **table_names, int tables) my_free(table_names_comma_sep); } else + { for (; tables > 0; tables--, table_names++) { table= *table_names; @@ -596,6 +597,7 @@ static int process_selected_tables(char *db, char **table_names, int tables) continue; handle_request_for_tables(table, table_len, view == 1, opt_all_in_1); } + } DBUG_RETURN(0); } /* process_selected_tables */ @@ -669,7 +671,7 @@ static int process_all_tables_in_db(char *database) size_t tot_length = 0; char *views, *views_end; - uint tot_views_length = 0; + size_t tot_views_length = 0; while ((row = mysql_fetch_row(res))) { @@ -915,16 +917,29 @@ static int handle_request_for_tables(char *tables, size_t length, } break; case DO_ANALYZE: + if (view) + { + printf("%-50s %s\n", tables, "Can't run anaylyze on a view"); + DBUG_RETURN(1); + } DBUG_ASSERT(!view); op= (opt_write_binlog) ? "ANALYZE" : "ANALYZE NO_WRITE_TO_BINLOG"; if (opt_persistent_all) end = strmov(end, " PERSISTENT FOR ALL"); break; case DO_OPTIMIZE: - DBUG_ASSERT(!view); + if (view) + { + printf("%-50s %s\n", tables, "Can't run optimize on a view"); + DBUG_RETURN(1); + } op= (opt_write_binlog) ? "OPTIMIZE" : "OPTIMIZE NO_WRITE_TO_BINLOG"; break; case DO_FIX_NAMES: - DBUG_ASSERT(!view); + if (view) + { + printf("%-50s %s\n", tables, "Can't run fix names on a view"); + DBUG_RETURN(1); + } DBUG_RETURN(fix_table_storage_name(tables)); } @@ -953,7 +968,7 @@ static int handle_request_for_tables(char *tables, size_t length, } if (verbose >= 3) puts(query); - if (mysql_real_query(sock, query, query_length)) + if (mysql_real_query(sock, query, (ulong)query_length)) { my_snprintf(message, sizeof(message), "when executing '%s%s... %s'", op, tab_view, options); @@ -965,7 +980,7 @@ static int handle_request_for_tables(char *tables, size_t length, if (opt_flush_tables) { query_length= sprintf(query, "FLUSH TABLES %s", table_name); - if (mysql_real_query(sock, query, query_length)) + if (mysql_real_query(sock, query, (ulong)query_length)) { DBerror(sock, query); my_free(query); diff --git a/client/mysqldump.c b/client/mysqldump.c index f0c53052a1f..d4932094dac 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2017, MariaDB Corporation. + Copyright (c) 2010, 2019, MariaDB Corporation. 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 @@ -39,7 +39,7 @@ ** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov */ -#define DUMP_VERSION "10.16" +#define DUMP_VERSION "10.17" #include <my_global.h> #include <my_sys.h> @@ -93,7 +93,7 @@ static void add_load_option(DYNAMIC_STRING *str, const char *option, const char *option_value); static ulong find_set(TYPELIB *, const char *, size_t, char **, uint *); -static char *alloc_query_str(ulong size); +static char *alloc_query_str(size_t size); static void field_escape(DYNAMIC_STRING* in, const char *from); static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_no_data_med= 1, @@ -115,10 +115,11 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_no_data_m opt_events= 0, opt_comments_used= 0, opt_alltspcs=0, opt_notspcs= 0, opt_logging, opt_drop_trigger= 0 ; -static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0; +static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0, + select_field_names_inited= 0; static ulong opt_max_allowed_packet, opt_net_buffer_length; static MYSQL mysql_connection,*mysql=0; -static DYNAMIC_STRING insert_pat; +static DYNAMIC_STRING insert_pat, select_field_names; static char *opt_password=0,*current_user=0, *current_host=0,*path=0,*fields_terminated=0, *lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0, @@ -170,7 +171,7 @@ wrappers, they will terminate the process if there is an allocation failure. */ static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str, - uint init_alloc, uint alloc_increment); + size_t init_alloc, size_t alloc_increment); static void dynstr_append_checked(DYNAMIC_STRING* dest, const char* src); static void dynstr_set_checked(DYNAMIC_STRING *str, const char *init_str); static void dynstr_append_mem_checked(DYNAMIC_STRING *str, const char *append, @@ -211,7 +212,9 @@ TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1, #define MED_ENGINES "MRG_MyISAM, MRG_ISAM, CONNECT, OQGRAPH, SPIDER, VP, FEDERATED" -HASH ignore_table; +static HASH ignore_table; + +static HASH ignore_database; static struct my_option my_long_options[] = { @@ -375,6 +378,11 @@ static struct my_option my_long_options[] = &opt_hex_blob, &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", ¤t_host, ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"ignore-database", OPT_IGNORE_DATABASE, + "Do not dump the specified database. To specify more than one database to ignore, " + "use the directive multiple times, once for each database. Only takes effect " + "when used together with --all-databases|-A", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"ignore-table", OPT_IGNORE_TABLE, "Do not dump the specified table. To specify more than one table to ignore, " "use the directive multiple times, once for each table. Each table must " @@ -899,6 +907,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case (int) OPT_TABLES: opt_databases=0; break; + case (int) OPT_IGNORE_DATABASE: + if (my_hash_insert(&ignore_database, (uchar*) my_strdup(argument, MYF(0)))) + exit(EX_EOM); + break; case (int) OPT_IGNORE_TABLE: { if (!strchr(argument, '.')) @@ -987,6 +999,9 @@ static int get_options(int *argc, char ***argv) load_defaults_or_exit("my", load_default_groups, argc, argv); defaults_argv= *argv; + if (my_hash_init(&ignore_database, charset_info, 16, 0, 0, + (my_hash_get_key) get_table_key, my_free, 0)) + return(EX_EOM); if (my_hash_init(&ignore_table, charset_info, 16, 0, 0, (my_hash_get_key) get_table_key, my_free, 0)) return(EX_EOM); @@ -998,7 +1013,9 @@ static int get_options(int *argc, char ***argv) my_hash_insert(&ignore_table, (uchar*) my_strdup("mysql.general_log", MYF(MY_WME))) || my_hash_insert(&ignore_table, - (uchar*) my_strdup("mysql.slow_log", MYF(MY_WME)))) + (uchar*) my_strdup("mysql.slow_log", MYF(MY_WME))) || + my_hash_insert(&ignore_table, + (uchar*) my_strdup("mysql.transaction_registry", MYF(MY_WME)))) return(EX_EOM); if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option))) @@ -1057,6 +1074,13 @@ static int get_options(int *argc, char ***argv) my_progname_short); return(EX_USAGE); } + if (ignore_database.records && !opt_alldbs) + { + fprintf(stderr, + "%s: --ignore-database can only be used together with --all-databases.\n", + my_progname_short); + return(EX_USAGE); + } if (strcmp(default_charset, MYSQL_AUTODETECT_CHARSET_NAME) && !(charset_info= get_charset_by_csname(default_charset, MY_CS_PRIMARY, MYF(MY_WME)))) @@ -1283,8 +1307,8 @@ get_binlog_gtid_pos(char *binlog_pos_file, char *binlog_pos_offset, if (len_pos_file >= FN_REFLEN || len_pos_offset > LONGLONG_LEN) return 0; - mysql_real_escape_string(mysql, file_buf, binlog_pos_file, len_pos_file); - mysql_real_escape_string(mysql, offset_buf, binlog_pos_offset, len_pos_offset); + mysql_real_escape_string(mysql, file_buf, binlog_pos_file, (ulong)len_pos_file); + mysql_real_escape_string(mysql, offset_buf, binlog_pos_offset, (ulong)len_pos_offset); init_dynamic_string_checked(&query, "SELECT BINLOG_GTID_POS('", 256, 1024); dynstr_append_checked(&query, file_buf); dynstr_append_checked(&query, "', '"); @@ -1534,7 +1558,7 @@ static int switch_character_set_results(MYSQL *mysql, const char *cs_name) "SET SESSION character_set_results = '%s'", (const char *) cs_name); - return mysql_real_query(mysql, query_buffer, query_length); + return mysql_real_query(mysql, query_buffer, (ulong)query_length); } /** @@ -1646,11 +1670,14 @@ static void free_resources() my_free(opt_password); my_free(current_host); free_root(&glob_root, MYF(0)); + if (my_hash_inited(&ignore_database)) + my_hash_free(&ignore_database); if (my_hash_inited(&ignore_table)) my_hash_free(&ignore_table); dynstr_free(&extended_row); dynstr_free(&dynamic_where); dynstr_free(&insert_pat); + dynstr_free(&select_field_names); if (defaults_argv) free_defaults(defaults_argv); mysql_library_end(); @@ -2121,7 +2148,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name, { create_stmt_ptr= (*row)[i]; create_stmt_len= lengths[i]; -#ifndef DBUG_OFF +#ifdef DBUG_ASSERT_EXISTS body_found= 1; #endif } @@ -2484,16 +2511,25 @@ static void print_blob_as_hex(FILE *output_file, const char *str, ulong len) static uint dump_routines_for_db(char *db) { char query_buff[QUERY_LENGTH]; - const char *routine_type[]= {"FUNCTION", "PROCEDURE"}; + const char *routine_type[]= {"FUNCTION", + "PROCEDURE", + "PACKAGE", + "PACKAGE BODY"}; + const char *create_caption_xml[]= {"Create Function", + "Create Procedure", + "Create Package", + "Create Package Body"}; char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3]; char *routine_name; - int i; + uint i; FILE *sql_file= md_result_file; MYSQL_ROW row, routine_list_row; char db_cl_name[MY_CS_NAME_SIZE]; int db_cl_altered= FALSE; - + // before 10.3 packages are not supported + uint upper_bound= mysql_get_server_version(mysql) >= 100300 ? + array_elements(routine_type) : 2; DBUG_ENTER("dump_routines_for_db"); DBUG_PRINT("enter", ("db: '%s'", db)); @@ -2522,8 +2558,8 @@ static uint dump_routines_for_db(char *db) if (opt_xml) fputs("\t<routines>\n", sql_file); - /* 0, retrieve and dump functions, 1, procedures */ - for (i= 0; i <= 1; i++) + /* 0, retrieve and dump functions, 1, procedures, etc. */ + for (i= 0; i < upper_bound; i++) { my_snprintf(query_buff, sizeof(query_buff), "SHOW %s STATUS WHERE Db = '%s'", @@ -2573,12 +2609,8 @@ static uint dump_routines_for_db(char *db) { if (opt_xml) { - if (i) /* Procedures. */ - print_xml_row(sql_file, "routine", routine_res, &row, - "Create Procedure"); - else /* Functions. */ - print_xml_row(sql_file, "routine", routine_res, &row, - "Create Function"); + print_xml_row(sql_file, "routine", routine_res, &row, + create_caption_xml[i]); continue; } if (opt_drop) @@ -2678,7 +2710,8 @@ static inline my_bool general_log_or_slow_log_tables(const char *db, { return (!my_strcasecmp(charset_info, db, "mysql")) && (!my_strcasecmp(charset_info, table, "general_log") || - !my_strcasecmp(charset_info, table, "slow_log")); + !my_strcasecmp(charset_info, table, "slow_log") || + !my_strcasecmp(charset_info, table, "transaction_registry")); } /* @@ -2716,7 +2749,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, "FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE " "TABLE_SCHEMA = %s AND TABLE_NAME = %s"; FILE *sql_file= md_result_file; - int len; + size_t len; my_bool is_log_table; MYSQL_RES *result; MYSQL_ROW row; @@ -2745,7 +2778,13 @@ static uint get_table_structure(char *table, char *db, char *table_type, else dynstr_set_checked(&insert_pat, ""); } - + if (!select_field_names_inited) + { + select_field_names_inited= 1; + init_dynamic_string_checked(&select_field_names, "", 1024, 1024); + } + else + dynstr_set_checked(&select_field_names, ""); insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " : delayed ? " DELAYED " : opt_ignore ? " IGNORE " : ""); @@ -2981,6 +3020,19 @@ static uint get_table_structure(char *table, char *db, char *table_type, DBUG_RETURN(0); } + while ((row= mysql_fetch_row(result))) + { + if (strlen(row[SHOW_EXTRA]) && strstr(row[SHOW_EXTRA],"INVISIBLE")) + complete_insert= 1; + if (init) + { + dynstr_append_checked(&select_field_names, ", "); + } + init=1; + dynstr_append_checked(&select_field_names, + quote_name(row[SHOW_FIELDNAME], name_buff, 0)); + } + init=0; /* If write_data is true, then we build up insert statements for the table's data. Note: in subsequent lines of code, this test @@ -3008,19 +3060,8 @@ static uint get_table_structure(char *table, char *db, char *table_type, } } - while ((row= mysql_fetch_row(result))) - { - if (complete_insert) - { - if (init) - { - dynstr_append_checked(&insert_pat, ", "); - } - init=1; - dynstr_append_checked(&insert_pat, - quote_name(row[SHOW_FIELDNAME], name_buff, 0)); - } - } + if (complete_insert) + dynstr_append_checked(&insert_pat, select_field_names.str); num_fields= mysql_num_rows(result); mysql_free_result(result); } @@ -3080,6 +3121,21 @@ static uint get_table_structure(char *table, char *db, char *table_type, while ((row= mysql_fetch_row(result))) { + if (strlen(row[SHOW_EXTRA]) && strstr(row[SHOW_EXTRA],"INVISIBLE")) + complete_insert= 1; + if (init) + { + dynstr_append_checked(&select_field_names, ", "); + } + dynstr_append_checked(&select_field_names, + quote_name(row[SHOW_FIELDNAME], name_buff, 0)); + init=1; + } + init=0; + mysql_data_seek(result, 0); + + while ((row= mysql_fetch_row(result))) + { ulong *lengths= mysql_fetch_lengths(result); if (init) { @@ -3595,7 +3651,7 @@ static void field_escape(DYNAMIC_STRING* in, const char *from) -static char *alloc_query_str(ulong size) +static char *alloc_query_str(size_t size) { char *query; @@ -3630,8 +3686,10 @@ static void dump_table(char *table, char *db) char table_type[NAME_LEN]; char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table; int error= 0; - ulong rownr, row_break, total_length, init_length; + ulong rownr, row_break; uint num_fields; + size_t total_length, init_length; + MYSQL_RES *res; MYSQL_FIELD *field; MYSQL_ROW row; @@ -3717,7 +3775,9 @@ static void dump_table(char *table, char *db) /* now build the query string */ - dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '"); + dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ "); + dynstr_append_checked(&query_string, select_field_names.str); + dynstr_append_checked(&query_string, " INTO OUTFILE '"); dynstr_append_checked(&query_string, filename); dynstr_append_checked(&query_string, "'"); @@ -3753,7 +3813,7 @@ static void dump_table(char *table, char *db) order_by= 0; } - if (mysql_real_query(mysql, query_string.str, query_string.length)) + if (mysql_real_query(mysql, query_string.str, (ulong)query_string.length)) { dynstr_free(&query_string); DB_error(mysql, "when executing 'SELECT INTO OUTFILE'"); @@ -3766,7 +3826,9 @@ static void dump_table(char *table, char *db) "\n--\n-- Dumping data for table %s\n--\n", fix_for_comment(result_table)); - dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM "); + dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ "); + dynstr_append_checked(&query_string, select_field_names.str); + dynstr_append_checked(&query_string, " FROM "); dynstr_append_checked(&query_string, result_table); if (where) @@ -4039,7 +4101,7 @@ static void dump_table(char *table, char *db) if (extended_insert) { - ulong row_length; + size_t row_length; dynstr_append_checked(&extended_row,")"); row_length= 2 + extended_row.length; if (total_length + row_length < opt_net_buffer_length) @@ -4183,6 +4245,7 @@ static int dump_tablespaces_for_tables(char *db, char **table_names, int tables) return r; } + static int dump_tablespaces_for_databases(char** databases) { int r; @@ -4212,6 +4275,7 @@ static int dump_tablespaces_for_databases(char** databases) return r; } + static int dump_tablespaces(char* ts_where) { MYSQL_ROW row; @@ -4242,7 +4306,8 @@ static int dump_tablespaces(char* ts_where) " EXTRA" " FROM INFORMATION_SCHEMA.FILES" " WHERE FILE_TYPE = 'UNDO LOG'" - " AND FILE_NAME IS NOT NULL", + " AND FILE_NAME IS NOT NULL" + " AND LOGFILE_GROUP_NAME IS NOT NULL", 256, 1024); if(ts_where) { @@ -4257,7 +4322,7 @@ static int dump_tablespaces(char* ts_where) } dynstr_append_checked(&sqlbuf, " GROUP BY LOGFILE_GROUP_NAME, FILE_NAME" - ", ENGINE" + ", ENGINE, TOTAL_EXTENTS, INITIAL_SIZE" " ORDER BY LOGFILE_GROUP_NAME"); if (mysql_query(mysql, sqlbuf.str) || @@ -4398,6 +4463,14 @@ static int dump_tablespaces(char* ts_where) DBUG_RETURN(0); } + +/* Return 1 if we should copy the database */ +static my_bool include_database(const char *hash_key) +{ + return !my_hash_search(&ignore_database, (uchar*) hash_key, strlen(hash_key)); +} + + static int dump_all_databases() { MYSQL_ROW row; @@ -4416,8 +4489,9 @@ static int dump_all_databases() !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME)) continue; - if (dump_all_tables_in_db(row[0])) - result=1; + if (include_database(row[0])) + if (dump_all_tables_in_db(row[0])) + result=1; } mysql_free_result(tableres); if (seen_views) @@ -4439,8 +4513,9 @@ static int dump_all_databases() !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME)) continue; - if (dump_all_views_in_db(row[0])) - result=1; + if (include_database(row[0])) + if (dump_all_views_in_db(row[0])) + result=1; } mysql_free_result(tableres); } @@ -4473,7 +4548,7 @@ static int dump_databases(char **db_names) /* -View Specific database initalization. +View Specific database initialization. SYNOPSIS init_dumping_views @@ -4490,7 +4565,7 @@ int init_dumping_views(char *qdatabase __attribute__((unused))) /* -Table Specific database initalization. +Table Specific database initialization. SYNOPSIS init_dumping_tables @@ -4592,6 +4667,7 @@ static int dump_all_tables_in_db(char *database) char hash_key[2*NAME_LEN+2]; /* "db.tablename" */ char *afterdot; my_bool general_log_table_exists= 0, slow_log_table_exists=0; + my_bool transaction_registry_table_exists= 0; int using_mysql_db= !my_strcasecmp(charset_info, database, "mysql"); DBUG_ENTER("dump_all_tables_in_db"); @@ -4617,7 +4693,7 @@ static int dump_all_tables_in_db(char *database) dynstr_append_checked(&query, " READ /*!32311 LOCAL */,"); } } - if (numrows && mysql_real_query(mysql, query.str, query.length-1)) + if (numrows && mysql_real_query(mysql, query.str, (ulong)query.length-1)) { dynstr_free(&query); DB_error(mysql, "when using LOCK TABLES"); @@ -4694,6 +4770,8 @@ static int dump_all_tables_in_db(char *database) general_log_table_exists= 1; else if (!my_strcasecmp(charset_info, table, "slow_log")) slow_log_table_exists= 1; + else if (!my_strcasecmp(charset_info, table, "transaction_registry")) + transaction_registry_table_exists= 1; } } } @@ -4740,6 +4818,13 @@ static int dump_all_tables_in_db(char *database) verbose_msg("-- Warning: get_table_structure() failed with some internal " "error for 'slow_log' table\n"); } + if (transaction_registry_table_exists) + { + if (!get_table_structure((char *) "transaction_registry", + database, table_type, &ignore_flag) ) + verbose_msg("-- Warning: get_table_structure() failed with some internal " + "error for 'transaction_registry' table\n"); + } } if (flush_privileges && using_mysql_db) { @@ -4791,7 +4876,7 @@ static my_bool dump_all_views_in_db(char *database) dynstr_append_checked(&query, " READ /*!32311 LOCAL */,"); } } - if (numrows && mysql_real_query(mysql, query.str, query.length-1)) + if (numrows && mysql_real_query(mysql, query.str, (ulong)query.length-1)) DB_error(mysql, "when using LOCK TABLES"); /* We shall continue here, if --force was given */ dynstr_free(&query); @@ -4943,7 +5028,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) if (init_dumping(db, init_dumping_tables)) DBUG_RETURN(1); - init_alloc_root(&glob_root, 8192, 0, MYF(0)); + init_alloc_root(&glob_root, "glob_root", 8192, 0, MYF(0)); if (!(dump_tables= pos= (char**) alloc_root(&glob_root, tables * sizeof(char *)))) die(EX_EOM, "alloc_root failure."); @@ -4987,7 +5072,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) !my_strcasecmp(&my_charset_latin1, db, PERFORMANCE_SCHEMA_DB_NAME))) { if (mysql_real_query(mysql, lock_tables_query.str, - lock_tables_query.length-1)) + (ulong)lock_tables_query.length-1)) { if (!ignore_errors) { @@ -5654,7 +5739,7 @@ static char *primary_key_fields(const char *table_name) MYSQL_ROW row; /* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */ char show_keys_buff[15 + NAME_LEN * 2 + 3]; - uint result_length= 0; + size_t result_length= 0; char *result= 0; char buff[NAME_LEN * 2 + 3]; char *quoted_field; @@ -5972,7 +6057,7 @@ static my_bool get_view_structure(char *table, char* db) #define DYNAMIC_STR_ERROR_MSG "Couldn't perform DYNAMIC_STRING operation" static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str, - uint init_alloc, uint alloc_increment) + size_t init_alloc, size_t alloc_increment) { if (init_dynamic_string(str, init_str, init_alloc, alloc_increment)) die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); @@ -6015,7 +6100,6 @@ int main(int argc, char **argv) sf_leaking_memory=1; /* don't report memory leaks on early exits */ compatible_mode_normal_str[0]= 0; default_charset= (char *)mysql_universal_client_charset; - bzero((char*) &ignore_table, sizeof(ignore_table)); exit_code= get_options(&argc, &argv); if (exit_code) diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 9d8239fe6db..32ad74dd5d1 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -419,7 +419,7 @@ static void lock_table(MYSQL *mysql, int tablecount, char **raw_tablename) dynstr_append(&query, tablename); dynstr_append(&query, " WRITE,"); } - if (mysql_real_query(mysql, query.str, query.length-1)) + if (mysql_real_query(mysql, query.str, (ulong)query.length-1)) db_error(mysql); /* We shall countinue here, if --force was given */ } diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 47dc7212ca2..dfa1eac3673 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -662,7 +662,7 @@ static int list_table_status(MYSQL *mysql,const char *db,const char *wild) { char query[NAME_LEN + 100]; - int len; + size_t len; MYSQL_RES *result; MYSQL_ROW row; @@ -909,7 +909,7 @@ static void print_res_header(MYSQL_RES *result) static void print_res_top(MYSQL_RES *result) { - uint i,length; + size_t i,length; MYSQL_FIELD *field; putchar('+'); @@ -917,7 +917,7 @@ static void print_res_top(MYSQL_RES *result) while((field = mysql_fetch_field(result))) { if ((length= strlen(field->name)) > field->max_length) - field->max_length=length; + field->max_length=(ulong)length; else length=field->max_length; for (i=length+2 ; i--> 0 ; ) diff --git a/client/mysqlslap.c b/client/mysqlslap.c index fae2553a188..b0d51463e2d 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -144,7 +144,7 @@ static unsigned long connect_flags= CLIENT_MULTI_RESULTS | CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS; -static int verbose, delimiter_length; +static int verbose; static uint commit_rate; static uint detach_rate; const char *num_int_cols_opt; @@ -263,7 +263,7 @@ void option_cleanup(option_string *stmt); void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr); static int run_statements(MYSQL *mysql, statement *stmt); int slap_connect(MYSQL *mysql); -static int run_query(MYSQL *mysql, const char *query, int len); +static int run_query(MYSQL *mysql, const char *query, size_t len); static const char ALPHANUMERICS[]= "0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz"; @@ -339,9 +339,6 @@ int main(int argc, char **argv) if (auto_generate_sql) srandom((uint)time(NULL)); - /* globals? Yes, so we only have to run strlen once */ - delimiter_length= strlen(delimiter); - if (argc > 2) { fprintf(stderr,"%s: Too many arguments\n",my_progname); @@ -1548,18 +1545,18 @@ get_options(int *argc,char ***argv) } -static int run_query(MYSQL *mysql, const char *query, int len) +static int run_query(MYSQL *mysql, const char *query, size_t len) { if (opt_only_print) { - printf("%.*s;\n", len, query); + printf("%.*s;\n", (int)len, query); return 0; } if (verbose >= 3) - printf("%.*s;\n", len, query); + printf("%.*s;\n", (int)len, query); - return mysql_real_query(mysql, query, len); + return mysql_real_query(mysql, query, (ulong)len); } @@ -2127,7 +2124,7 @@ parse_delimiter(const char *script, statement **stmt, char delm) char *ptr= (char *)script; statement **sptr= stmt; statement *tmp; - uint length= strlen(script); + size_t length= strlen(script); uint count= 0; /* We know that there is always one */ for (tmp= *sptr= (statement *)my_malloc(sizeof(statement), diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 60a203ccedd..696872ee32c 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -187,7 +187,7 @@ static uint opt_connect_timeout= 0; static uint opt_wait_for_pos_timeout= 0; static char delimiter[MAX_DELIMITER_LENGTH]= ";"; -static uint delimiter_length= 1; +static size_t delimiter_length= 1; static char TMPDIR[FN_REFLEN]; static char global_subst_from[200]; @@ -269,8 +269,8 @@ static void free_re(void); static char *get_string(char **to_ptr, char **from_ptr, struct st_command *command); static int replace(DYNAMIC_STRING *ds_str, - const char *search_str, ulong search_len, - const char *replace_str, ulong replace_len); + const char *search_str, size_t search_len, + const char *replace_str, size_t replace_len); static uint opt_protocol=0; @@ -295,11 +295,11 @@ const char *result_file_name= 0; typedef struct { char *name; - int name_len; + size_t name_len; char *str_val; - int str_val_len; + size_t str_val_len; int int_val; - int alloced_len; + size_t alloced_len; bool int_dirty; /* do not update string if int is updated until first read */ bool is_int; bool alloced; @@ -581,7 +581,7 @@ struct st_replace_regex *glob_replace_regex= 0; struct st_replace; struct st_replace *glob_replace= 0; void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds, -const char *from, int len); +const char *from); ATTRIBUTE_NORETURN static void cleanup_and_exit(int exit_code); @@ -598,20 +598,19 @@ void verbose_msg(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2); void log_msg(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2); VAR* var_from_env(const char *, const char *); -VAR* var_init(VAR* v, const char *name, int name_len, const char *val, - int val_len); +VAR* var_init(VAR* v, const char *name, size_t name_len, const char *val, size_t val_len); VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw, my_bool ignore_not_existing); void eval_expr(VAR* v, const char *p, const char** p_end, bool open_end=false, bool do_eval=true); -my_bool match_delimiter(int c, const char *delim, uint length); +my_bool match_delimiter(int c, const char *delim, size_t length); void dump_result_to_reject_file(char *buf, int size); void dump_warning_messages(); void do_eval(DYNAMIC_STRING *query_eval, const char *query, const char *query_end, my_bool pass_through_escape_chars); -void str_to_file(const char *fname, char *str, int size); -void str_to_file2(const char *fname, char *str, int size, my_bool append); +void str_to_file(const char *fname, char *str, size_t size); +void str_to_file2(const char *fname, char *str, size_t size, my_bool append); void fix_win_paths(char *val, size_t len); const char *get_errname_from_code (uint error_code); @@ -710,6 +709,8 @@ public: void write(DYNAMIC_STRING* ds) { DBUG_ENTER("LogFile::write"); + DBUG_PRINT("enter", ("length: %u", (uint) ds->length)); + DBUG_ASSERT(m_file); if (ds->length == 0) @@ -1086,9 +1087,9 @@ static void init_connection_thd(struct st_connection *cn) #else /* ! EMBEDDED_LIBRARY*/ #define init_connection_thd(X) do { } while(0) -#define do_send_query(cn,q,q_len) mysql_send_query(cn->mysql, q, q_len) +#define do_send_query(cn,q,q_len) mysql_send_query(cn->mysql, q, (ulong)q_len) #define do_read_query_result(cn) mysql_read_query_result(cn->mysql) -#define do_stmt_prepare(cn, q, q_len) mysql_stmt_prepare(cn->stmt, q, q_len) +#define do_stmt_prepare(cn, q, q_len) mysql_stmt_prepare(cn->stmt, q, (ulong)q_len) #define do_stmt_execute(cn) mysql_stmt_execute(cn->stmt) #define do_stmt_close(cn) mysql_stmt_close(cn->stmt) @@ -1617,7 +1618,7 @@ static void make_error_message(char *buf, size_t len, const char *fmt, va_list a fmt= "unknown error"; s+= my_vsnprintf(s, end - s, fmt, args); - s+= my_snprintf(s, end -s, "\n", start_lineno); + s+= my_snprintf(s, end -s, "\n"); } void die(const char *fmt, ...) @@ -2149,8 +2150,8 @@ int compare_files2(File fd1, const char* filename2) 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); + size_t global_subst_from_len= strlen(global_subst_from); + size_t 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) @@ -2221,8 +2222,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) DBUG_ENTER("dyn_string_cmp"); DBUG_PRINT("enter", ("fname: %s", fname)); - if ((fd= create_temp_file(temp_file_path, TMPDIR, - "tmp", O_CREAT | O_SHARE | O_RDWR, + if ((fd= create_temp_file(temp_file_path, TMPDIR, "tmp", O_SHARE, MYF(MY_WME))) < 0) die("Failed to create temporary file for ds"); @@ -2432,10 +2432,9 @@ void var_check_int(VAR *v) } -VAR *var_init(VAR *v, const char *name, int name_len, const char *val, - int val_len) +VAR *var_init(VAR *v, const char *name, size_t name_len, const char *val, size_t val_len) { - int val_alloc_len; + size_t val_alloc_len; VAR *tmp_var; if (!name_len && name) name_len = strlen(name); @@ -2736,7 +2735,8 @@ void var_query_set(VAR *var, const char *query, const char** query_end) init_dynamic_string(&ds_query, 0, (end - query) + 32, 256); do_eval(&ds_query, query, end, FALSE); - if (mysql_real_query(mysql, ds_query.str, ds_query.length) || !(res= mysql_store_result(mysql))) + if (mysql_real_query(mysql, ds_query.str, (ulong)ds_query.length) || + !(res= mysql_store_result(mysql))) { handle_error(curr_command, mysql_errno(mysql), mysql_error(mysql), mysql_sqlstate(mysql), &ds_res); @@ -2766,7 +2766,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end) { /* Add column to tab separated string */ char *val= row[i]; - int len= lengths[i]; + size_t len= lengths[i]; if (glob_replace_regex) { @@ -2779,7 +2779,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end) } if (glob_replace) - replace_strings_append(glob_replace, &result, val, len); + replace_strings_append(glob_replace, &result, val); else dynstr_append_mem(&result, val, len); } @@ -2917,7 +2917,7 @@ void var_set_query_get_value(struct st_command *command, VAR *var) die("Mismatched \"'s around query '%s'", ds_query.str); /* Run the query */ - if (mysql_real_query(mysql, ds_query.str, ds_query.length)) + if (mysql_real_query(mysql, ds_query.str, (ulong)ds_query.length)) { handle_error(curr_command, mysql_errno(mysql), mysql_error(mysql), mysql_sqlstate(mysql), &ds_res); @@ -3064,7 +3064,7 @@ void eval_expr(VAR *v, const char *p, const char **p_end, struct st_command command; memset(&command, 0, sizeof(command)); command.query= (char*)p; - command.first_word_len= len; + command.first_word_len= (int)len; command.first_argument= command.query + len; command.end= (char*)*p_end; command.abort_on_error= 1; /* avoid uninitialized variables */ @@ -3075,11 +3075,11 @@ void eval_expr(VAR *v, const char *p, const char **p_end, NO_EVAL: { - int new_val_len = (p_end && *p_end) ? - (int) (*p_end - p) : (int) strlen(p); + size_t new_val_len = (p_end && *p_end) ? + (size_t)(*p_end - p) : strlen(p); if (new_val_len + 1 >= v->alloced_len) { - static int MIN_VAR_ALLOC= 32; + static size_t MIN_VAR_ALLOC= 32; v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ? MIN_VAR_ALLOC : new_val_len + 1; if (!(v->str_val = @@ -3335,8 +3335,8 @@ static void init_builtin_echo(void) */ static int replace(DYNAMIC_STRING *ds_str, - const char *search_str, ulong search_len, - const char *replace_str, ulong replace_len) + const char *search_str, size_t search_len, + const char *replace_str, size_t replace_len) { DYNAMIC_STRING ds_tmp; const char *start= strstr(ds_str->str, search_str); @@ -4639,8 +4639,7 @@ void do_perl(struct st_command *command) /* Create temporary file name */ if ((fd= create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"), - "tmp", O_CREAT | O_SHARE | O_RDWR, - MYF(MY_WME))) < 0) + "tmp", O_SHARE, MYF(MY_WME))) < 0) die("Failed to create temporary file for perl command"); my_close(fd, MYF(0)); @@ -5095,7 +5094,9 @@ int query_get_string(MYSQL* mysql, const char* query, static int my_kill(int pid, int sig) { + DBUG_PRINT("info", ("Killing server, pid: %d", pid)); #ifdef _WIN32 +#define SIGKILL 9 /* ignored anyway, see below */ HANDLE proc; if ((proc= OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, pid)) == NULL) return -1; @@ -5130,6 +5131,26 @@ static int my_kill(int pid, int sig) */ + +static int wait_until_dead(int pid, int timeout) +{ + DBUG_ENTER("wait_until_dead"); + /* Check that server dies */ + while (timeout--) + { + if (my_kill(pid, 0) < 0) + { + DBUG_PRINT("info", ("Process %d does not exist anymore", pid)); + DBUG_RETURN(0); + } + DBUG_PRINT("info", ("Sleeping, timeout: %d", timeout)); + /* Sleep one second */ + my_sleep(1000000L); + } + DBUG_RETURN(1); // Did not die +} + + void do_shutdown_server(struct st_command *command) { long timeout= opt_wait_for_pos_timeout ? opt_wait_for_pos_timeout / 5 : 300; @@ -5181,24 +5202,31 @@ void do_shutdown_server(struct st_command *command) } DBUG_PRINT("info", ("Got pid %d", pid)); - /* Tell server to shutdown if timeout > 0*/ + /* + If timeout == 0, it means we should kill the server hard, without + any shutdown or core (SIGKILL) + + If timeout is given, then we do things in the following order: + - mysql_shutdown() + - If server is not dead within timeout + - kill SIGABRT (to get a core) + - If server is not dead within new timeout + - kill SIGKILL + */ + if (timeout && mysql_shutdown(mysql, SHUTDOWN_DEFAULT)) die("mysql_shutdown failed"); - /* Check that server dies */ - while(timeout--){ - if (my_kill(pid, 0) < 0){ - DBUG_PRINT("info", ("Process %d does not exist anymore", pid)); - DBUG_VOID_RETURN; + if (!timeout || wait_until_dead(pid, timeout)) + { + if (timeout) + (void) my_kill(pid, SIGABRT); + /* Give server a few seconds to die in all cases */ + if (!timeout || wait_until_dead(pid, timeout < 5 ? 5 : timeout)) + { + (void) my_kill(pid, SIGKILL); } - DBUG_PRINT("info", ("Sleeping, timeout: %ld", timeout)); - my_sleep(1000000L); } - - /* Kill the server */ - DBUG_PRINT("info", ("Killing server, pid: %d", pid)); - (void)my_kill(pid, 9); - DBUG_VOID_RETURN; } @@ -6504,7 +6532,7 @@ static void do_reset_connection() } -my_bool match_delimiter(int c, const char *delim, uint length) +my_bool match_delimiter(int c, const char *delim, size_t length) { uint i; char tmp[MAX_DELIMITER_LENGTH]; @@ -6932,6 +6960,7 @@ int read_command(struct st_command** command_ptr) if (parser.current_line < parser.read_lines) { get_dynamic(&q_lines, command_ptr, parser.current_line) ; + DBUG_PRINT("info", ("query: %s", (*command_ptr)->query)); DBUG_RETURN(0); } if (!(*command_ptr= command= @@ -7365,7 +7394,7 @@ int parse_args(int argc, char **argv) append - append to file instead of overwriting old file */ -void str_to_file2(const char *fname, char *str, int size, my_bool append) +void str_to_file2(const char *fname, char *str, size_t size, my_bool append) { int fd; char buff[FN_REFLEN]; @@ -7399,7 +7428,7 @@ void str_to_file2(const char *fname, char *str, int size, my_bool append) size - size of content witten to file */ -void str_to_file(const char *fname, char *str, int size) +void str_to_file(const char *fname, char *str, size_t size) { str_to_file2(fname, str, size, FALSE); } @@ -7926,7 +7955,7 @@ static void handle_no_active_connection(struct st_command *command, */ void run_query_normal(struct st_connection *cn, struct st_command *command, - int flags, char *query, int query_len, + int flags, char *query, size_t query_len, DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings) { MYSQL_RES *res= 0; @@ -8271,7 +8300,7 @@ void handle_no_error(struct st_command *command) */ void run_query_stmt(struct st_connection *cn, struct st_command *command, - char *query, int query_len, DYNAMIC_STRING *ds, + char *query, size_t query_len, DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings) { MYSQL_RES *res= NULL; /* Note that here 'res' is meta data result set */ @@ -8558,7 +8587,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) DYNAMIC_STRING ds_sorted; DYNAMIC_STRING ds_warnings; char *query; - int query_len; + size_t query_len; my_bool view_created= 0, sp_created= 0; my_bool complete_query= ((flags & QUERY_SEND_FLAG) && (flags & QUERY_REAP_FLAG)); @@ -8614,7 +8643,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) if (!disable_query_log && (flags & QUERY_SEND_FLAG)) { char *print_query= query; - int print_len= query_len; + size_t print_len= query_len; if (flags & QUERY_PRINT_ORIGINAL_FLAG) { print_query= command->query; @@ -8811,7 +8840,7 @@ void init_re_comp(regex_t *re, const char* str) if (err) { char erbuf[100]; - int len= regerror(err, re, erbuf, sizeof(erbuf)); + size_t len= regerror(err, re, erbuf, sizeof(erbuf)); die("error %s, %d/%d `%s'\n", re_eprint(err), (int)len, (int)sizeof(erbuf), erbuf); } @@ -8916,7 +8945,7 @@ int match_re(regex_t *re, char *str) { char erbuf[100]; - int len= regerror(err, re, erbuf, sizeof(erbuf)); + size_t len= regerror(err, re, erbuf, sizeof(erbuf)); die("error %s, %d/%d `%s'\n", re_eprint(err), (int)len, (int)sizeof(erbuf), erbuf); } @@ -9061,7 +9090,7 @@ static void dump_backtrace(void) #endif } fputs("Attempting backtrace...\n", stderr); - my_print_stacktrace(NULL, (ulong)my_thread_stack_size); + my_print_stacktrace(NULL, (ulong)my_thread_stack_size, 0); } #else @@ -9229,7 +9258,7 @@ int main(int argc, char **argv) read_command_buf= (char*)my_malloc(read_command_buflen= 65536, MYF(MY_FAE)); init_dynamic_string(&ds_res, "", 2048, 2048); - init_alloc_root(&require_file_root, 1024, 1024, MYF(0)); + init_alloc_root(&require_file_root, "require_file", 1024, 1024, MYF(0)); parse_args(argc, argv); @@ -10061,8 +10090,7 @@ typedef struct st_replace_found { void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds, - const char *str, - int len __attribute__((unused))) + const char *str) { REPLACE *rep_pos; REPLACE_STRING *rep_str; @@ -10105,7 +10133,6 @@ void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds, DBUG_PRINT("exit", ("Found end of from string")); DBUG_VOID_RETURN; } - DBUG_ASSERT(from <= str+len); start= from; rep_pos=rep; } @@ -10169,7 +10196,7 @@ struct st_replace_regex* init_replace_regex(char* expr) { char *expr_end, *buf_p; struct st_replace_regex* res; - uint expr_len= strlen(expr); + size_t expr_len= strlen(expr); /* my_malloc() will die on fail with MY_FAE */ res=(struct st_replace_regex*)my_malloc( @@ -10552,7 +10579,7 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern, regfree(&r); *res_p= 0; *buf_p= buf; - *buf_len_p= buf_len; + *buf_len_p= (int)buf_len; return 0; } @@ -11195,7 +11222,7 @@ void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, size_t len) if (glob_replace) { /* Normal replace */ - replace_strings_append(glob_replace, ds, val, len); + replace_strings_append(glob_replace, ds, val); } else dynstr_append_mem(ds, val, len); |