diff options
Diffstat (limited to 'client/mysqltest.cc')
-rw-r--r-- | client/mysqltest.cc | 664 |
1 files changed, 372 insertions, 292 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 598fb54e72e..7d2b4b3b0a7 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2009, 2017, 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 @@ -49,7 +49,7 @@ #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif -#ifdef __WIN__ +#ifdef _WIN32 #include <direct.h> #endif #include <signal.h> @@ -57,7 +57,7 @@ #include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE -#ifdef __WIN__ +#ifdef _WIN32 #include <crtdbg.h> #define SIGNAL_FMT "exception 0x%x" #else @@ -82,7 +82,7 @@ static my_bool non_blocking_api_enabled= 0; #define MAX_DELIMITER_LENGTH 16 #define DEFAULT_MAX_CONN 64 -#define DIE_BUFF_SIZE 8192 +#define DIE_BUFF_SIZE 256*1024 /* Flags controlling send and reap */ #define QUERY_SEND_FLAG 1 @@ -125,9 +125,10 @@ static my_bool view_protocol= 0, view_protocol_enabled= 0; static my_bool cursor_protocol= 0, cursor_protocol_enabled= 0; static my_bool parsing_disabled= 0; static my_bool display_result_vertically= FALSE, display_result_lower= FALSE, - display_metadata= FALSE, display_result_sorted= FALSE; + display_metadata= FALSE, display_result_sorted= FALSE, + display_session_track_info= FALSE; static my_bool disable_query_log= 0, disable_result_log= 0; -static my_bool disable_connect_log= 1; +static my_bool disable_connect_log= 0; static my_bool disable_warnings= 0, disable_column_names= 0; static my_bool prepare_warnings_enabled= 0; static my_bool disable_info= 1; @@ -153,6 +154,7 @@ static struct property prop_list[] = { { &abort_on_error, 0, 1, 0, "$ENABLED_ABORT_ON_ERROR" }, { &disable_connect_log, 0, 1, 1, "$ENABLED_CONNECT_LOG" }, { &disable_info, 0, 1, 1, "$ENABLED_INFO" }, + { &display_session_track_info, 0, 1, 1, "$ENABLED_STATE_CHANGE_INFO" }, { &display_metadata, 0, 0, 0, "$ENABLED_METADATA" }, { &ps_protocol_enabled, 0, 0, 0, "$ENABLED_PS_PROTOCOL" }, { &disable_query_log, 0, 0, 1, "$ENABLED_QUERY_LOG" }, @@ -166,6 +168,7 @@ enum enum_prop { P_ABORT= 0, P_CONNECT, P_INFO, + P_SESSION_TRACK, P_META, P_PS, P_QUERY, @@ -190,7 +193,10 @@ static char TMPDIR[FN_REFLEN]; static char global_subst_from[200]; static char global_subst_to[200]; static char *global_subst= NULL; +static char *read_command_buf= NULL; static MEM_ROOT require_file_root; +static const my_bool my_true= 1; +static const my_bool my_false= 0; /* Block stack */ enum block_cmd { @@ -360,6 +366,7 @@ enum enum_commands { Q_WAIT_FOR_SLAVE_TO_STOP, Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS, Q_ENABLE_INFO, Q_DISABLE_INFO, + Q_ENABLE_SESSION_TRACK_INFO, Q_DISABLE_SESSION_TRACK_INFO, Q_ENABLE_METADATA, Q_DISABLE_METADATA, Q_ENABLE_COLUMN_NAMES, Q_DISABLE_COLUMN_NAMES, Q_EXEC, Q_DELIMITER, @@ -382,6 +389,7 @@ enum enum_commands { Q_RESULT_FORMAT_VERSION, Q_MOVE_FILE, Q_REMOVE_FILES_WILDCARD, Q_SEND_EVAL, Q_ENABLE_PREPARE_WARNINGS, Q_DISABLE_PREPARE_WARNINGS, + Q_RESET_CONNECTION, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ Q_COMMENT_WITH_COMMAND, @@ -433,6 +441,8 @@ const char *command_names[]= "disable_warnings", "enable_info", "disable_info", + "enable_session_track_info", + "disable_session_track_info", "enable_metadata", "disable_metadata", "enable_column_names", @@ -466,7 +476,7 @@ const char *command_names[]= "copy_file", "perl", "die", - + /* Don't execute any more commands, compare result */ "exit", "skip", @@ -489,6 +499,7 @@ const char *command_names[]= "send_eval", "enable_prepare_warnings", "disable_prepare_warnings", + "reset_connection", 0 }; @@ -572,15 +583,17 @@ struct st_replace *glob_replace= 0; void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds, const char *from, int len); -static void cleanup_and_exit(int exit_code) __attribute__((noreturn)); +ATTRIBUTE_NORETURN +static void cleanup_and_exit(int exit_code); -void really_die(const char *msg) __attribute__((noreturn)); -void report_or_die(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2); -void die(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2) - __attribute__((noreturn)); +ATTRIBUTE_NORETURN +static void really_die(const char *msg); +void report_or_die(const char *fmt, ...); +ATTRIBUTE_NORETURN +static void die(const char *fmt, ...); static void make_error_message(char *buf, size_t len, const char *fmt, va_list args); -void abort_not_supported_test(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2) - __attribute__((noreturn)); +ATTRIBUTE_NORETURN ATTRIBUTE_FORMAT(printf, 1, 2) +void abort_not_supported_test(const char *fmt, ...); void verbose_msg(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2); void log_msg(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2); @@ -600,11 +613,11 @@ void do_eval(DYNAMIC_STRING *query_eval, const char *query, 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 fix_win_paths(const char *val, size_t len); +void fix_win_paths(char *val, size_t len); const char *get_errname_from_code (uint error_code); int multi_reg_replace(struct st_replace_regex* r,char* val); -#ifdef __WIN__ +#ifdef _WIN32 void free_tmp_sh_file(); void free_win_path_patterns(); #endif @@ -704,7 +717,7 @@ public: DBUG_ASSERT(ds->str); #ifdef EXTRA_DEBUG - DBUG_PRINT("QQ", ("str: %*s", (int) ds->length, ds->str)); + DBUG_DUMP("extra", (uchar*) ds->str, ds->length); #endif if (fwrite(ds->str, 1, ds->length, m_file) != ds->length) @@ -763,7 +776,7 @@ public: if (show_from != buf) { // The last new line was found in this buf, adjust offset - show_offset+= (show_from - buf) + 1; + show_offset+= (int)(show_from - buf) + 1; DBUG_PRINT("info", ("adjusted offset to %d", show_offset)); } DBUG_PRINT("info", ("show_offset: %d", show_offset)); @@ -832,6 +845,47 @@ void revert_properties(); static void handle_no_active_connection(struct st_command* command, struct st_connection *cn, DYNAMIC_STRING *ds); + +/* Wrapper for fgets.Strips \r off newlines on Windows. + Should be used with together with my_popen(). +*/ +static char *my_fgets(char * s, int n, FILE * stream, int *len) +{ + char *buf = fgets(s, n, stream); + if (!buf) + { + *len= 0; + return buf; + } + + *len = (int)strlen(buf); +#ifdef _WIN32 + /* Strip '\r' off newlines. */ + if (*len > 1 && buf[*len - 2] == '\r' && buf[*len - 1] == '\n') + { + buf[*len - 2]= '\n'; + buf[*len - 1]= 0; + (*len)--; + } +#endif + return buf; +} + +/* + Wrapper for popen(). + On Windows, uses binary mode to workaround + C runtime bug mentioned in MDEV-9409 +*/ +static FILE* my_popen(const char *cmd, const char *mode) +{ + FILE *f= popen(cmd, mode); +#ifdef _WIN32 + if (f) + _setmode(fileno(f), O_BINARY); +#endif + return f; +} + #ifdef EMBEDDED_LIBRARY #define EMB_SEND_QUERY 1 @@ -1029,7 +1083,7 @@ static void init_connection_thd(struct st_connection *cn) cn->has_thread=TRUE; } -#else /*EMBEDDED_LIBRARY*/ +#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) @@ -1095,9 +1149,7 @@ void do_eval(DYNAMIC_STRING *query_eval, const char *query, break; } } -#ifdef __WIN__ - fix_win_paths(query_eval->str, query_eval->length); -#endif + fix_win_paths(query_eval->str, query_eval->length); DBUG_VOID_RETURN; } @@ -1260,7 +1312,7 @@ void check_command_args(struct st_command *command, /* Check required arg */ if (arg->ds->length == 0 && arg->required) - die("Missing required argument '%s' to command '%.*s'", arg->argname, + die("Missing required argument '%s' to command '%.*b'", arg->argname, command->first_word_len, command->query); } @@ -1269,7 +1321,7 @@ void check_command_args(struct st_command *command, while(ptr <= command->end && *ptr != '#') { if (*ptr && *ptr != ' ') - die("Extra argument '%s' passed to '%.*s'", + die("Extra argument '%s' passed to '%.*b'", ptr, command->first_word_len, command->query); ptr++; } @@ -1289,7 +1341,7 @@ void handle_command_error(struct st_command *command, uint error, if (command->abort_on_error) { - report_or_die("command \"%.*s\" failed with error: %u my_errno: %d " + report_or_die("command \"%.*b\" failed with error: %u my_errno: %d " "errno: %d", command->first_word_len, command->query, error, my_errno, sys_errno); @@ -1307,7 +1359,7 @@ void handle_command_error(struct st_command *command, uint error, DBUG_VOID_RETURN; } if (command->expected_errors.count > 0) - report_or_die("command \"%.*s\" failed with wrong error: %u " + report_or_die("command \"%.*b\" failed with wrong error: %u " "my_errno: %d errno: %d", command->first_word_len, command->query, error, my_errno, sys_errno); @@ -1316,7 +1368,7 @@ void handle_command_error(struct st_command *command, uint error, command->expected_errors.err[0].code.errnum != 0) { /* Error code we wanted was != 0, i.e. not an expected success */ - report_or_die("command \"%.*s\" succeeded - should have failed with " + report_or_die("command \"%.*b\" succeeded - should have failed with " "errno %d...", command->first_word_len, command->query, command->expected_errors.err[0].code.errnum); @@ -1415,7 +1467,8 @@ void free_used_memory() free_defaults(default_argv); free_root(&require_file_root, MYF(0)); free_re(); -#ifdef __WIN__ + my_free(read_command_buf); +#ifdef _WIN32 free_tmp_sh_file(); free_win_path_patterns(); #endif @@ -1502,7 +1555,7 @@ static void make_error_message(char *buf, size_t len, const char *fmt, va_list a s+= my_snprintf(s, end -s, "\n", start_lineno); } -void die(const char *fmt, ...) +static void die(const char *fmt, ...) { char buff[DIE_BUFF_SIZE]; va_list args; @@ -1511,7 +1564,7 @@ void die(const char *fmt, ...) really_die(buff); } -void really_die(const char *msg) +static void really_die(const char *msg) { static int dying= 0; fflush(stdout); @@ -1575,6 +1628,7 @@ void abort_not_supported_test(const char *fmt, ...) cur_file->file_name, cur_file->lineno); char buff[DIE_BUFF_SIZE]; + buff[0] = '\0'; print_file_stack(buff, buff + sizeof(buff)); fprintf(stderr, "%s", buff); @@ -1719,19 +1773,20 @@ static int run_command(char* cmd, DBUG_ENTER("run_command"); DBUG_PRINT("enter", ("cmd: %s", cmd)); - if (!(res_file= popen(cmd, "r"))) + if (!(res_file= my_popen(cmd, "r"))) { report_or_die("popen(\"%s\", \"r\") failed", cmd); DBUG_RETURN(-1); } - while (fgets(buf, sizeof(buf), res_file)) + int len; + while (my_fgets(buf, sizeof(buf), res_file, &len)) { DBUG_PRINT("info", ("buf: %s", buf)); if(ds_res) { /* Save the output of this command in the supplied string */ - dynstr_append(ds_res, buf); + dynstr_append_mem(ds_res, buf,len); } else { @@ -1787,7 +1842,7 @@ static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...) va_end(args); -#ifdef __WIN__ +#ifdef _WIN32 dynstr_append(&ds_cmdline, "\""); #endif @@ -1810,7 +1865,7 @@ static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...) not present. */ -#ifdef __WIN__ +#ifdef _WIN32 static int diff_check(const char *diff_name) { @@ -1820,14 +1875,15 @@ static int diff_check(const char *diff_name) my_snprintf(buf, sizeof(buf), "%s -v", diff_name); - if (!(res_file= popen(buf, "r"))) + if (!(res_file= my_popen(buf, "r"))) die("popen(\"%s\", \"r\") failed", buf); /* if diff is not present, nothing will be in stdout to increment have_diff */ - if (fgets(buf, sizeof(buf), res_file)) + int len; + if (my_fgets(buf, sizeof(buf), res_file, &len)) have_diff= 1; pclose(res_file); @@ -1867,7 +1923,7 @@ void show_diff(DYNAMIC_STRING* ds, in order to correctly detect non-availibility of 'diff', and the way it's implemented does not work with default 'diff' on Solaris. */ -#ifdef __WIN__ +#ifdef _WIN32 if (diff_check("diff")) diff_name = "diff"; else if (diff_check("mtrdiff")) @@ -1930,7 +1986,7 @@ void show_diff(DYNAMIC_STRING* ds, "two files was shown for you to diff manually.\n\n" "To get a better report you should install 'diff' on your system, which you\n" "for example can get from http://www.gnu.org/software/diffutils/diffutils.html\n" -#ifdef __WIN__ +#ifdef _WIN32 "or http://gnuwin32.sourceforge.net/packages/diffutils.htm\n" #endif "\n"); @@ -2266,7 +2322,7 @@ static int strip_surrounding(char* str, char c1, char c2) static void strip_parentheses(struct st_command *command) { if (strip_surrounding(command->first_argument, '(', ')')) - die("%.*s - argument list started with '%c' must be ended with '%c'", + die("%.*b - argument list started with '%c' must be ended with '%c'", command->first_word_len, command->query, '(', ')'); } @@ -2591,7 +2647,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end) DBUG_ASSERT(query_end); memset(&command, 0, sizeof(command)); command.query= (char*)query; - command.first_word_len= (*query_end - query); + command.first_word_len= (int)(*query_end - query); command.first_argument= command.query + command.first_word_len; command.end= (char*)*query_end; command.abort_on_error= 1; /* avoid uninitialized variables */ @@ -2922,7 +2978,7 @@ void eval_expr(VAR *v, const char *p, const char **p_end, /* Make sure there was just a $variable and nothing else */ const char* end= *p_end + 1; if (end < expected_end && !open_end) - die("Found junk '%.*s' after $variable in expression", + die("Found junk '%.*b' after $variable in expression", (int)(expected_end - end - 1), end); DBUG_VOID_RETURN; @@ -2995,7 +3051,7 @@ void open_file(const char *name) { char buff[FN_REFLEN]; size_t length; - const char *curname= cur_file->file_name; + char *curname= cur_file->file_name; DBUG_ENTER("open_file"); DBUG_PRINT("enter", ("name: %s", name)); @@ -3038,9 +3094,7 @@ void open_file(const char *name) 5.try in basedir */ -#ifdef __WIN__ fix_win_paths(curname, sizeof(curname)); -#endif bool in_overlay= opt_overlay_dir && !strncmp(curname, opt_overlay_dir, overlay_dir_len); @@ -3148,7 +3202,7 @@ void do_source(struct st_command *command) } -#if defined __WIN__ +#if defined _WIN32 #ifdef USE_CYGWIN /* Variables used for temporary sh files used for emulating Unix on Windows */ @@ -3175,21 +3229,9 @@ void free_tmp_sh_file() #endif -FILE* my_popen(DYNAMIC_STRING *ds_cmd, const char *mode) -{ -#if defined __WIN__ && defined USE_CYGWIN - /* Dump the command into a sh script file and execute with popen */ - str_to_file(tmp_sh_name, ds_cmd->str, ds_cmd->length); - return popen(tmp_sh_cmd, mode); -#else - return popen(ds_cmd->str, mode); -#endif -} - - static void init_builtin_echo(void) { -#ifdef __WIN__ +#ifdef _WIN32 size_t echo_length; /* Look for "echo.exe" in same dir as mysqltest was started from */ @@ -3301,7 +3343,7 @@ void do_exec(struct st_command *command) replace(&ds_cmd, "echo", 4, builtin_echo, strlen(builtin_echo)); } -#ifdef __WIN__ +#ifdef _WIN32 #ifndef USE_CYGWIN /* Replace /dev/null with NUL */ while(replace(&ds_cmd, "/dev/null", 9, "NUL", 3) == 0) @@ -3321,7 +3363,7 @@ void do_exec(struct st_command *command) DBUG_PRINT("info", ("Executing '%s' as '%s'", command->first_argument, ds_cmd.str)); - if (!(res_file= my_popen(&ds_cmd, "r"))) + if (!(res_file= my_popen(ds_cmd.str, "r"))) { dynstr_free(&ds_cmd); if (command->abort_on_error) @@ -3335,24 +3377,9 @@ void do_exec(struct st_command *command) init_dynamic_string(&ds_sorted, "", 1024, 1024); ds_result= &ds_sorted; } - -#ifdef _WIN32 - /* Workaround for CRT bug, MDEV-9409 */ - _setmode(fileno(res_file), O_BINARY); -#endif - - while (fgets(buf, sizeof(buf), res_file)) + int len; + while (my_fgets(buf, sizeof(buf), res_file,&len)) { - int len = (int)strlen(buf); -#ifdef _WIN32 - /* Strip '\r' off newlines. */ - if (len > 1 && buf[len-2] == '\r' && buf[len-1] == '\n') - { - buf[len-2] = '\n'; - buf[len-1] = 0; - len--; - } -#endif replace_dynstr_append_mem(ds_result, buf, len); } error= pclose(res_file); @@ -3445,10 +3472,10 @@ int do_modify_var(struct st_command *command, const char *p= command->first_argument; VAR* v; if (!*p) - die("Missing argument to %.*s", command->first_word_len, + die("Missing argument to %.*b", command->first_word_len, command->query); if (*p != '$') - die("The argument to %.*s must be a variable (start with $)", + die("The argument to %.*b must be a variable (start with $)", command->first_word_len, command->query); v= var_get(p, &p, 1, 0); if (! v->is_int) @@ -3483,7 +3510,7 @@ int do_modify_var(struct st_command *command, int my_system(DYNAMIC_STRING* ds_cmd) { -#if defined __WIN__ && defined USE_CYGWIN +#if defined _WIN32 && defined USE_CYGWIN /* Dump the command into a sh script file and execute with system */ str_to_file(tmp_sh_name, ds_cmd->str, ds_cmd->length); return system(tmp_sh_cmd); @@ -3522,7 +3549,7 @@ void do_system(struct st_command *command) /* Eval the system command, thus replacing all environment variables */ do_eval(&ds_cmd, command->first_argument, command->end, !is_windows); -#ifdef __WIN__ +#ifdef _WIN32 #ifndef USE_CYGWIN /* Replace /dev/null with NUL */ while(replace(&ds_cmd, "/dev/null", 9, "NUL", 3) == 0) @@ -3930,63 +3957,6 @@ void do_mkdir(struct st_command *command) } -/* - Remove directory recursively. -*/ -static int rmtree(const char *dir) -{ - char path[FN_REFLEN]; - char sep[]={ FN_LIBCHAR, 0 }; - int err=0; - - MY_DIR *dir_info= my_dir(dir, MYF(MY_DONT_SORT | MY_WANT_STAT)); - if (!dir_info) - return 1; - - for (uint i= 0; i < dir_info->number_of_files; i++) - { - FILEINFO *file= dir_info->dir_entry + i; - /* Skip "." and ".." */ - if (!strcmp(file->name, ".") || !strcmp(file->name, "..")) - continue; - - strxnmov(path, sizeof(path), dir, sep, file->name, NULL); - - if (!MY_S_ISDIR(file->mystat->st_mode)) - { - err= my_delete(path, 0); -#ifdef _WIN32 - /* - On Windows, check and possible reset readonly attribute. - my_delete(), or DeleteFile does not remove these files. - */ - if (err) - { - DWORD attr= GetFileAttributes(path); - if (attr != INVALID_FILE_ATTRIBUTES && - (attr & FILE_ATTRIBUTE_READONLY)) - { - SetFileAttributes(path, attr &~ FILE_ATTRIBUTE_READONLY); - err= my_delete(path, 0); - } - } -#endif - } - else - err= rmtree(path); - - if(err) - break; - } - - my_dirend(dir_info); - - if (!err) - err= rmdir(dir); - - return err; -} - /* SYNOPSIS @@ -4014,7 +3984,7 @@ void do_rmdir(struct st_command *command) DBUG_VOID_RETURN; DBUG_PRINT("info", ("removing directory: %s", ds_dirname.str)); - if (rmtree(ds_dirname.str)) + if (my_rmtree(ds_dirname.str, MYF(0))) handle_command_error(command, 1, errno); dynstr_free(&ds_dirname); @@ -4611,10 +4581,18 @@ void do_perl(struct st_command *command) str_to_file(temp_file_path, ds_script.str, ds_script.length); + /* Use the same perl executable as the one that runs mysql-test-run.pl */ + const char *mtr_perl=getenv("MTR_PERL"); + if (!mtr_perl) + mtr_perl="perl"; + /* Format the "perl <filename>" command */ - my_snprintf(buf, sizeof(buf), "perl %s", temp_file_path); + if (strchr(mtr_perl, ' ')) + my_snprintf(buf, sizeof(buf), "\"%s\" %s", mtr_perl, temp_file_path); + else + my_snprintf(buf, sizeof(buf), "%s %s", mtr_perl, temp_file_path); - if (!(res_file= popen(buf, "r"))) + if (!(res_file= my_popen(buf, "r"))) { if (command->abort_on_error) die("popen(\"%s\", \"r\") failed", buf); @@ -4622,16 +4600,17 @@ void do_perl(struct st_command *command) DBUG_VOID_RETURN; } - while (fgets(buf, sizeof(buf), res_file)) + int len; + while (my_fgets(buf, sizeof(buf), res_file,&len)) { if (disable_result_log) { - buf[strlen(buf)-1]=0; - DBUG_PRINT("exec_result",("%s", buf)); + buf[len - 1] = 0; + DBUG_PRINT("exec_result", ("%s", buf)); } else { - replace_dynstr_append(&ds_res, buf); + replace_dynstr_append_mem(&ds_res, buf, len); } } error= pclose(res_file); @@ -4642,7 +4621,7 @@ void do_perl(struct st_command *command) /* Check for error code that indicates perl could not be started */ int exstat= WEXITSTATUS(error); -#ifdef __WIN__ +#ifdef _WIN32 if (exstat == 1) /* Text must begin 'perl not found' as mtr looks for it */ abort_not_supported_test("perl not found in path or did not start"); @@ -4774,18 +4753,18 @@ void do_sync_with_master2(struct st_command *command, long offset, information is not initialized, the arguments are incorrect, or an error has occurred */ - die("%.*s failed: '%s' returned NULL " \ + die("%.*b failed: '%s' returned NULL " \ "indicating slave SQL thread failure", command->first_word_len, command->query, query_buf); } if (result == -1) - die("%.*s failed: '%s' returned -1 " \ + die("%.*b failed: '%s' returned -1 " \ "indicating timeout after %d seconds", command->first_word_len, command->query, query_buf, timeout); else - die("%.*s failed: '%s' returned unknown result :%d", + die("%.*b failed: '%s' returned unknown result :%d", command->first_word_len, command->query, query_buf, result); } @@ -4798,7 +4777,7 @@ void do_sync_with_master(struct st_command *command) char *p= command->first_argument; const char *offset_start= p; char *start, *buff= 0; - start= (char*) ""; + start= const_cast<char*>(""); if (*offset_start) { @@ -4950,17 +4929,17 @@ int do_sleep(struct st_command *command, my_bool real_sleep) while (my_isspace(charset_info, *p)) p++; if (!*p) - die("Missing argument to %.*s", command->first_word_len, + die("Missing argument to %.*b", command->first_word_len, command->query); sleep_start= p; /* Check that arg starts with a digit, not handled by my_strtod */ if (!my_isdigit(charset_info, *sleep_start)) - die("Invalid argument to %.*s \"%s\"", command->first_word_len, + die("Invalid argument to %.*b \"%s\"", command->first_word_len, command->query, sleep_start); sleep_val= my_strtod(sleep_start, &sleep_end, &error); check_eol_junk_line(sleep_end); if (error) - die("Invalid argument to %.*s \"%s\"", command->first_word_len, + die("Invalid argument to %.*b \"%s\"", command->first_word_len, command->query, command->first_argument); dynstr_free(&ds_sleep); @@ -5048,7 +5027,7 @@ int query_get_string(MYSQL* mysql, const char* query, static int my_kill(int pid, int sig) { -#ifdef __WIN__ +#ifdef _WIN32 HANDLE proc; if ((proc= OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, pid)) == NULL) return -1; @@ -5122,8 +5101,7 @@ void do_shutdown_server(struct st_command *command) die("Failed to open file '%s'", ds_pidfile_name.str); dynstr_free(&ds_pidfile_name); - if (my_read(fd, (uchar*)&buff, - sizeof(buff), MYF(0)) <= 0){ + if (my_read(fd, (uchar*)&buff, sizeof(buff), MYF(0)) <= 0){ my_close(fd, MYF(0)); die("pid file was empty"); } @@ -5214,6 +5192,7 @@ uint get_errcode_from_name(const char *error_name, const char *error_end) handler_error_names))) return tmp; die("Unknown SQL error name '%s'", error_name); + return 0; // Keep compiler happy } const char *unknown_error= "<Unknown>"; @@ -5478,18 +5457,6 @@ static char *get_string(char **to_ptr, char **from_ptr, } -void set_reconnect(MYSQL* mysql, my_bool val) -{ - my_bool reconnect= val; - DBUG_ENTER("set_reconnect"); - DBUG_PRINT("info", ("val: %d", (int) val)); -#if MYSQL_VERSION_ID < 50000 - mysql->reconnect= reconnect; -#else - mysql_options(mysql, MYSQL_OPT_RECONNECT, (char *)&reconnect); -#endif - DBUG_VOID_RETURN; -} /** @@ -5574,11 +5541,7 @@ void do_close_connection(struct st_command *command) #ifndef EMBEDDED_LIBRARY if (command->type == Q_DIRTY_CLOSE) { - if (con->mysql->net.vio) - { - vio_delete(con->mysql->net.vio); - con->mysql->net.vio = 0; - } + mariadb_cancel(con->mysql); } #endif /*!EMBEDDED_LIBRARY*/ if (con->stmt) @@ -5861,6 +5824,7 @@ void do_connect(struct st_command *command) int read_timeout= 0; int write_timeout= 0; int connect_timeout= 0; + char *csname=0; struct st_connection* con_slot; static DYNAMIC_STRING ds_connection_name; @@ -5972,8 +5936,13 @@ void do_connect(struct st_command *command) { connect_timeout= atoi(con_options + sizeof("connect_timeout=")-1); } + else if (strncasecmp(con_options, "CHARSET=", + sizeof("CHARSET=") - 1) == 0) + { + csname= strdup(con_options + sizeof("CHARSET=") - 1); + } else - die("Illegal option to connect: %.*s", + die("Illegal option to connect: %.*b", (int) (end - con_options), con_options); /* Process next option */ con_options= end; @@ -6008,7 +5977,7 @@ void do_connect(struct st_command *command) if (opt_compress || con_compress) mysql_options(con_slot->mysql, MYSQL_OPT_COMPRESS, NullS); mysql_options(con_slot->mysql, MYSQL_SET_CHARSET_NAME, - charset_info->csname); + csname?csname: charset_info->csname); if (opt_charsets_dir) mysql_options(con_slot->mysql, MYSQL_SET_CHARSET_DIR, opt_charsets_dir); @@ -6035,7 +6004,7 @@ void do_connect(struct st_command *command) if (con_pipe) { -#ifdef __WIN__ +#ifdef _WIN32 opt_protocol= MYSQL_PROTOCOL_PIPE; #endif } @@ -6124,6 +6093,7 @@ void do_connect(struct st_command *command) #ifdef HAVE_SMEM dynstr_free(&ds_shm); #endif + free(csname); DBUG_VOID_RETURN; } @@ -6299,7 +6269,7 @@ void do_block(enum block_cmd cmd, struct st_command* command) enum block_op operand= find_operand(curr_ptr); if (operand == ILLEG_OP) - die("Found junk '%.*s' after $variable in condition", + die("Found junk '%.*b' after $variable in condition", (int)(expr_end - curr_ptr), curr_ptr); /* We could silently allow this, but may be confusing */ @@ -6430,7 +6400,7 @@ void do_delimiter(struct st_command* command) if (!(*p)) die("Can't set empty delimiter"); - delimiter_length= strmake_buf(delimiter, p) - delimiter; + delimiter_length= (uint)(strmake_buf(delimiter, p) - delimiter); DBUG_PRINT("exit", ("delimiter: %s", delimiter)); command->last_argument= p + delimiter_length; @@ -6438,6 +6408,34 @@ void do_delimiter(struct st_command* command) } +/* + do_reset_connection + + DESCRIPTION + Reset the current session. +*/ + +static void do_reset_connection() +{ +#ifndef EMBEDDED_LIBRARY + MYSQL *mysql = cur_con->mysql; + + DBUG_ENTER("do_reset_connection"); + if (mysql_reset_connection(mysql)) + die("reset connection failed: %s", mysql_error(mysql)); + if (cur_con->stmt) + { + mysql_stmt_close(cur_con->stmt); + cur_con->stmt= NULL; + } + DBUG_VOID_RETURN; +#else + die("reset connection failed: unsupported by embedded server client library"); + return; +#endif +} + + my_bool match_delimiter(int c, const char *delim, uint length) { uint i; @@ -6500,7 +6498,6 @@ static inline bool is_escape_char(char c, char in_string) */ -static char *read_command_buf= NULL; static size_t read_command_buflen= 0; static const size_t max_multibyte_length= 6; @@ -6684,37 +6681,35 @@ int read_line() if (!skip_char) { - /* Could be a multibyte character */ - /* This code is based on the code in "sql_load.cc" */ -#ifdef USE_MB - int charlen = my_mbcharlen(charset_info, (unsigned char) c); - /* We give up if multibyte character is started but not */ - /* completed before we pass buf_end */ - if ((charlen > 1) && (p + charlen) <= buf_end) + *p++= c; + if (use_mb(charset_info)) { - int i; - char* mb_start = p; - - *p++ = c; - - for (i= 1; i < charlen; i++) - { - c= my_getc(cur_file->file); - if (feof(cur_file->file)) - goto found_eof; - *p++ = c; - } - if (! my_ismbchar(charset_info, mb_start, p)) - { - /* It was not a multiline char, push back the characters */ - /* We leave first 'c', i.e. pretend it was a normal char */ - while (p-1 > mb_start) - my_ungetc(*--p); - } + const char *mb_start= p - 1; + /* Could be a multibyte character */ + /* See a similar code in "sql_load.cc" */ + for ( ; p < buf_end; ) + { + int charlen= my_charlen(charset_info, mb_start, p); + if (charlen > 0) + break; /* Full character */ + if (MY_CS_IS_TOOSMALL(charlen)) + { + /* We give up if multibyte character is started but not */ + /* completed before we pass buf_end */ + c= my_getc(cur_file->file); + if (feof(cur_file->file)) + goto found_eof; + *p++ = c; + continue; + } + DBUG_ASSERT(charlen == MY_CS_ILSEQ); + /* It was not a multiline char, push back the characters */ + /* We leave first 'c', i.e. pretend it was a normal char */ + while (p - 1 > mb_start) + my_ungetc(*--p); + break; + } } - else -#endif - *p++= c; } } DBUG_RETURN(0); @@ -6868,13 +6863,13 @@ int read_command(struct st_command** command_ptr) if (parser.current_line < parser.read_lines) { - get_dynamic(&q_lines, (uchar*) command_ptr, parser.current_line) ; + get_dynamic(&q_lines, command_ptr, parser.current_line) ; DBUG_RETURN(0); } if (!(*command_ptr= command= (struct st_command*) my_malloc(sizeof(*command), MYF(MY_WME|MY_ZEROFILL))) || - insert_dynamic(&q_lines, (uchar*) &command)) + insert_dynamic(&q_lines, &command)) die("Out of memory"); command->type= Q_UNKNOWN; @@ -6926,7 +6921,7 @@ int read_command(struct st_command** command_ptr) command->first_argument= p; command->end= strend(command->query); - command->query_len= (command->end - command->query); + command->query_len= (int)(command->end - command->query); parser.read_lines++; DBUG_RETURN(0); } @@ -7114,7 +7109,7 @@ void read_embedded_server_arguments(const char *name) if (!embedded_server_arg_count) { embedded_server_arg_count=1; - embedded_server_args[0]= (char*) ""; /* Progname */ + embedded_server_args[0]= const_cast<char*>(""); /* Progname */ } if (!(file=my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME)))) die("Failed to open file '%s'", buff); @@ -7124,7 +7119,7 @@ void read_embedded_server_arguments(const char *name) { *(strend(str)-1)=0; /* Remove end newline */ if (!(embedded_server_args[embedded_server_arg_count]= - (char*) my_strdup(str,MYF(MY_WME)))) + my_strdup(str, MYF(MY_WME)))) { my_fclose(file,MYF(0)); die("Out of memory"); @@ -7186,7 +7181,7 @@ get_one_option(int optid, const struct my_option *opt, char *argument) } case 'p': if (argument == disabled_my_option) - argument= (char*) ""; // Don't require password + argument= const_cast<char*>(""); // Don't require password if (argument) { my_free(opt_pass); @@ -7205,7 +7200,7 @@ get_one_option(int optid, const struct my_option *opt, char *argument) if (!embedded_server_arg_count) { embedded_server_arg_count=1; - embedded_server_args[0]= (char*) ""; + embedded_server_args[0]= const_cast<char*>(""); } if (embedded_server_arg_count == MAX_EMBEDDED_SERVER_ARGS-1 || !(embedded_server_args[embedded_server_arg_count++]= @@ -7354,7 +7349,7 @@ void check_regerr(regex_t* r, int err) } -#ifdef __WIN__ +#ifdef _WIN32 DYNAMIC_ARRAY patterns; @@ -7404,7 +7399,7 @@ void init_win_path_patterns() continue; } - if (insert_dynamic(&patterns, (uchar*) &p)) + if (insert_dynamic(&patterns, &p)) die("Out of memory"); DBUG_PRINT("info", ("p: %s", p)); @@ -7428,6 +7423,7 @@ void free_win_path_patterns() } delete_dynamic(&patterns); } +#endif /* fix_win_paths @@ -7443,8 +7439,9 @@ void free_win_path_patterns() => all \ from c:\mysql\m... until next space is converted into / */ -void fix_win_paths(const char *val, size_t len) +void fix_win_paths(char *val, size_t len) { +#ifdef _WIN32 uint i; char *p; @@ -7455,7 +7452,7 @@ void fix_win_paths(const char *val, size_t len) DBUG_PRINT("info", ("pattern: %s", *pattern)); /* Search for the path in string */ - while ((p= strstr((char*)val, *pattern))) + while ((p= strstr(val, *pattern))) { DBUG_PRINT("info", ("Found %s in val p: %s", *pattern, p)); @@ -7468,10 +7465,10 @@ void fix_win_paths(const char *val, size_t len) DBUG_PRINT("info", ("Converted \\ to /, p: %s", p)); } } - DBUG_PRINT("exit", (" val: %s, len: %d", val, len)); + DBUG_PRINT("exit", (" val: %s, len: %zu", val, len)); DBUG_VOID_RETURN; -} #endif +} @@ -7480,7 +7477,7 @@ void fix_win_paths(const char *val, size_t len) */ void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field, - char* val, ulonglong len, my_bool is_null) + char* val, size_t len, my_bool is_null) { char null[]= "NULL"; @@ -7494,7 +7491,7 @@ void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field, val= null; len= 4; } -#ifdef __WIN__ +#ifdef _WIN32 else if ((field->type == MYSQL_TYPE_DOUBLE || field->type == MYSQL_TYPE_FLOAT ) && field->decimals >= 31) @@ -7525,13 +7522,13 @@ void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field, { if (col_idx) dynstr_append_mem(ds, "\t", 1); - replace_dynstr_append_mem(ds, val, (int)len); + replace_dynstr_append_mem(ds, val, len); } else { dynstr_append(ds, field->name); dynstr_append_mem(ds, "\t", 1); - replace_dynstr_append_mem(ds, val, (int)len); + replace_dynstr_append_mem(ds, val, len); dynstr_append_mem(ds, "\n", 1); } } @@ -7669,8 +7666,7 @@ void append_metadata(DYNAMIC_STRING *ds, dynstr_append_mem(ds, "\t", 1); replace_dynstr_append_uint(ds, field->max_length); dynstr_append_mem(ds, "\t", 1); - dynstr_append_mem(ds, (char*) (IS_NOT_NULL(field->flags) ? - "N" : "Y"), 1); + dynstr_append_mem(ds, (IS_NOT_NULL(field->flags) ? "N" : "Y"), 1); dynstr_append_mem(ds, "\t", 1); replace_dynstr_append_uint(ds, field->flags); dynstr_append_mem(ds, "\t", 1); @@ -7701,6 +7697,70 @@ void append_info(DYNAMIC_STRING *ds, ulonglong affected_rows, } +/** + @brief Append state change information (received through Ok packet) to the output. + + @param [in,out] ds Dynamic string to hold the content to be printed. + @param [in] mysql Connection handle. +*/ + +static void append_session_track_info(DYNAMIC_STRING *ds, MYSQL *mysql) +{ +#ifndef EMBEDDED_LIBRARY + for (unsigned int type= SESSION_TRACK_BEGIN; type <= SESSION_TRACK_END; type++) + { + const char *data; + size_t data_length; + + if (!mysql_session_track_get_first(mysql, + (enum_session_state_type) type, + &data, &data_length)) + { + dynstr_append(ds, "-- "); + switch (type) + { + case SESSION_TRACK_SYSTEM_VARIABLES: + dynstr_append(ds, "Tracker : SESSION_TRACK_SYSTEM_VARIABLES\n"); + break; + case SESSION_TRACK_SCHEMA: + dynstr_append(ds, "Tracker : SESSION_TRACK_SCHEMA\n"); + break; + case SESSION_TRACK_STATE_CHANGE: + dynstr_append(ds, "Tracker : SESSION_TRACK_STATE_CHANGE\n"); + break; + case SESSION_TRACK_GTIDS: + dynstr_append(ds, "Tracker : SESSION_TRACK_GTIDS\n"); + break; + case SESSION_TRACK_TRANSACTION_CHARACTERISTICS: + dynstr_append(ds, "Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS\n"); + break; + case SESSION_TRACK_TRANSACTION_TYPE: + dynstr_append(ds, "Tracker : SESSION_TRACK_TRANSACTION_TYPE\n"); + break; + default: + DBUG_ASSERT(0); + dynstr_append(ds, "\n"); + } + + + dynstr_append(ds, "-- "); + dynstr_append_mem(ds, data, data_length); + } + else + continue; + while (!mysql_session_track_get_next(mysql, + (enum_session_state_type) type, + &data, &data_length)) + { + dynstr_append(ds, "\n-- "); + dynstr_append_mem(ds, data, data_length); + } + dynstr_append(ds, "\n\n"); + } +#endif /* EMBEDDED_LIBRARY */ +} + + /* Display the table headings with the names tab separated */ @@ -7881,6 +7941,9 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, if (!disable_info) append_info(ds, mysql_affected_rows(mysql), mysql_info(mysql)); + if (display_session_track_info) + append_session_track_info(ds, mysql); + /* Add all warnings to the result. We can't do this if we are in the middle of processing results from multi-statement, because @@ -8302,6 +8365,10 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, if (!disable_info) append_info(ds, mysql_stmt_affected_rows(stmt), mysql_info(mysql)); + if (display_session_track_info) + append_session_track_info(ds, mysql); + + if (!disable_warnings) { /* Get the warnings from execute */ @@ -8344,10 +8411,18 @@ end: revert_properties(); /* Close the statement if reconnect, need new prepare */ - if (mysql->reconnect) { - mysql_stmt_close(stmt); - cn->stmt= NULL; +#ifndef EMBEDDED_LIBRARY + my_bool reconnect; + mysql_get_option(mysql, MYSQL_OPT_RECONNECT, &reconnect); + if (reconnect) +#else + if (mysql->reconnect) +#endif + { + mysql_stmt_close(stmt); + cn->stmt= NULL; + } } DBUG_VOID_RETURN; @@ -8475,7 +8550,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) if (flags & QUERY_PRINT_ORIGINAL_FLAG) { print_query= command->query; - print_len= command->end - command->query; + print_len= (int)(command->end - command->query); } replace_dynstr_append_mem(ds, print_query, print_len); dynstr_append_mem(ds, delimiter, delimiter_length); @@ -8527,7 +8602,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) Yes, it was possible to create this query as a view */ view_created= 1; - query= (char*)"SELECT * FROM mysqltest_tmp_v"; + query= const_cast<char*>("SELECT * FROM mysqltest_tmp_v"); query_len = strlen(query); /* @@ -8574,7 +8649,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) { sp_created= 1; - query= (char*)"CALL mysqltest_tmp_sp()"; + query= const_cast<char*>("CALL mysqltest_tmp_sp()"); query_len = strlen(query); } dynstr_free(&query_str); @@ -8918,7 +8993,7 @@ static void dump_backtrace(void) #endif } fputs("Attempting backtrace...\n", stderr); - my_print_stacktrace(NULL, my_thread_stack_size); + my_print_stacktrace(NULL, (ulong)my_thread_stack_size); } #else @@ -8938,12 +9013,12 @@ static sig_handler signal_handler(int sig) fprintf(stderr, "Writing a core file...\n"); fflush(stderr); my_write_core(sig); -#ifndef __WIN__ +#ifndef _WIN32 exit(1); // Shouldn't get here but just in case #endif } -#ifdef __WIN__ +#ifdef _WIN32 LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp) { @@ -8980,17 +9055,13 @@ static void init_signal_handling(void) SetUnhandledExceptionFilter(exception_filter); } -#else /* __WIN__ */ +#else /* _WIN32 */ static void init_signal_handling(void) { struct sigaction sa; DBUG_ENTER("init_signal_handling"); -#ifdef HAVE_STACKTRACE - my_init_stacktrace(); -#endif - sa.sa_flags = SA_RESETHAND | SA_NODEFER; sigemptyset(&sa.sa_mask); sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL); @@ -9007,7 +9078,7 @@ static void init_signal_handling(void) DBUG_VOID_RETURN; } -#endif /* !__WIN__ */ +#endif /* !_WIN32 */ int main(int argc, char **argv) { @@ -9075,7 +9146,7 @@ int main(int argc, char **argv) memset(&var_reg, 0, sizeof(var_reg)); init_builtin_echo(); -#ifdef __WIN__ +#ifdef _WIN32 #ifndef USE_CYGWIN is_windows= 1; #endif @@ -9214,7 +9285,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) + while (!abort_flag && !read_command(&command)) { my_bool ok_to_do; int current_line_inc = 1, processed = 0; @@ -9314,6 +9385,12 @@ int main(int argc, char **argv) case Q_DISABLE_INFO: set_property(command, P_INFO, 1); break; + case Q_ENABLE_SESSION_TRACK_INFO: + set_property(command, P_SESSION_TRACK, 1); + break; + case Q_DISABLE_SESSION_TRACK_INFO: + set_property(command, P_SESSION_TRACK, 0); + break; case Q_ENABLE_METADATA: set_property(command, P_META, 1); break; @@ -9385,6 +9462,7 @@ int main(int argc, char **argv) case Q_LET: do_let(command); break; case Q_EVAL_RESULT: die("'eval_result' command is deprecated"); + break; // never called but keep compiler calm case Q_EVAL: case Q_EVALP: case Q_QUERY_VERTICAL: @@ -9524,6 +9602,9 @@ int main(int argc, char **argv) case Q_PING: handle_command_error(command, mysql_ping(cur_con->mysql), -1); break; + case Q_RESET_CONNECTION: + do_reset_connection(); + break; case Q_SEND_SHUTDOWN: handle_command_error(command, mysql_shutdown(cur_con->mysql, @@ -9562,10 +9643,10 @@ int main(int argc, char **argv) non_blocking_api_enabled= 1; break; case Q_DISABLE_RECONNECT: - set_reconnect(cur_con->mysql, 0); + mysql_options(cur_con->mysql, MYSQL_OPT_RECONNECT, &my_false); break; case Q_ENABLE_RECONNECT: - set_reconnect(cur_con->mysql, 1); + mysql_options(cur_con->mysql, MYSQL_OPT_RECONNECT, &my_true); /* Close any open statements - no reconnect, need new prepare */ close_statements(); break; @@ -9599,11 +9680,9 @@ int main(int argc, char **argv) do_eval(&ds_res, command->first_argument, command->end, FALSE); abort_not_supported_test("%s",ds_res.str); break; - case Q_RESULT: die("result, deprecated command"); break; - default: processed= 0; break; @@ -9854,8 +9933,8 @@ void do_get_replace(struct st_command *command) free_replace(); - bzero((char*) &to_array,sizeof(to_array)); - bzero((char*) &from_array,sizeof(from_array)); + bzero(&to_array,sizeof(to_array)); + bzero(&from_array,sizeof(from_array)); if (!*from) die("Missing argument in %s", command->query); start= buff= (char*)my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE)); @@ -9866,9 +9945,7 @@ void do_get_replace(struct st_command *command) if (!*from) die("Wrong number of arguments to replace_result in '%s'", command->query); -#ifdef __WIN__ fix_win_paths(to, from - to); -#endif insert_pointer_name(&from_array,to); to= get_string(&buff, &from, command); insert_pointer_name(&to_array,to); @@ -10103,13 +10180,14 @@ void append_replace_regex(char* expr, char *expr_end, struct st_replace_regex* r } /* done parsing the statement, now place it in regex_arr */ - if (insert_dynamic(&res->regex_arr,(uchar*) ®)) + if (insert_dynamic(&res->regex_arr, ®)) die("Out of memory"); } return; err: + my_free(res->regex_arr.buffer); my_free(res); die("Error parsing replace_regex \"%s\"", expr); } @@ -10150,7 +10228,7 @@ int multi_reg_replace(struct st_replace_regex* r,char* val) struct st_regex re; char* save_out_buf= out_buf; - get_dynamic(&r->regex_arr,(uchar*)&re,i); + get_dynamic(&r->regex_arr, &re, i); if (!reg_replace(&out_buf, buf_len_p, re.pattern, re.replace, in_buf, re.icase)) @@ -10216,7 +10294,7 @@ void free_replace_regex() */ #define SECURE_REG_BUF if (buf_len < need_buf_len) \ { \ - int off= res_p - buf; \ + ssize_t off= res_p - buf; \ buf= (char*)my_realloc(buf,need_buf_len,MYF(MY_WME+MY_FAE)); \ res_p= buf + off; \ buf_len= need_buf_len; \ @@ -10241,13 +10319,15 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern, regmatch_t *subs; char *replace_end; char *buf= *buf_p; - int len; - int buf_len, need_buf_len; + size_t len; + size_t buf_len, need_buf_len; int cflags= REG_EXTENDED | REG_DOTALL; int err_code; char *res_p,*str_p,*str_end; - buf_len= *buf_len_p; + DBUG_ASSERT(*buf_len_p > 0); + + buf_len= (size_t)*buf_len_p; len= strlen(string); str_end= string + len; @@ -10390,7 +10470,7 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern, } else /* no match this time, just copy the string as is */ { - int left_in_str= str_end-str_p; + size_t left_in_str= str_end-str_p; need_buf_len= (res_p-buf) + left_in_str; SECURE_REG_BUF memcpy(res_p,str_p,left_in_str); @@ -10509,7 +10589,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count, if (len > max_length) max_length=len; } - bzero((char*) is_word_end,sizeof(is_word_end)); + bzero(is_word_end, sizeof(is_word_end)); for (i=0 ; word_end_chars[i] ; i++) is_word_end[(uchar) word_end_chars[i]]=1; @@ -10600,7 +10680,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count, or_bits(sets.set+used_sets,sets.set); /* Can restart from start */ /* Find all chars that follows current sets */ - bzero((char*) used_chars,sizeof(used_chars)); + bzero(used_chars, sizeof(used_chars)); for (i= (uint) ~0; (i=get_next_bit(sets.set+used_sets,i)) ;) { used_chars[follow[i].chr]=1; @@ -10734,7 +10814,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count, int init_sets(REP_SETS *sets,uint states) { - bzero((char*) sets,sizeof(*sets)); + bzero(sets, sizeof(*sets)); sets->size_of_bits=((states+7)/8); if (!(sets->set_buffer=(REP_SET*) my_malloc(sizeof(REP_SET)*SET_MALLOC_HUNC, MYF(MY_WME)))) @@ -10765,8 +10845,8 @@ REP_SET *make_new_set(REP_SETS *sets) { sets->extra--; set=sets->set+ sets->count++; - bzero((char*) set->bits,sizeof(uint)*sets->size_of_bits); - bzero((char*) &set->next[0],sizeof(set->next[0])*LAST_CHAR_CODE); + bzero(set->bits, sizeof(uint) * sets->size_of_bits); + bzero(&set->next[0], sizeof(set->next[0]) * LAST_CHAR_CODE); set->found_offset=0; set->found_len=0; set->table_offset= (uint) ~0; @@ -10774,13 +10854,12 @@ REP_SET *make_new_set(REP_SETS *sets) return set; } count=sets->count+sets->invisible+SET_MALLOC_HUNC; - if (!(set=(REP_SET*) my_realloc((uchar*) sets->set_buffer, - sizeof(REP_SET)*count, + if (!(set=(REP_SET*) my_realloc(sets->set_buffer, sizeof(REP_SET)*count, MYF(MY_WME)))) return 0; sets->set_buffer=set; sets->set=set+sets->invisible; - if (!(bit_buffer=(uint*) my_realloc((uchar*) sets->bit_buffer, + if (!(bit_buffer=(uint*) my_realloc(sets->bit_buffer, (sizeof(uint)*sets->size_of_bits)*count, MYF(MY_WME)))) return 0; @@ -10831,7 +10910,7 @@ void or_bits(REP_SET *to,REP_SET *from) void copy_bits(REP_SET *to,REP_SET *from) { - memcpy((uchar*) to->bits,(uchar*) from->bits, + memcpy(to->bits, from->bits, (size_t) (sizeof(uint) * to->size_of_bits)); } @@ -10939,8 +11018,8 @@ int insert_pointer_name(POINTER_ARRAY *pa,char * name) (sizeof(char *)+sizeof(*pa->flag))* (sizeof(char *)+sizeof(*pa->flag))),MYF(MY_WME)))) DBUG_RETURN(-1); - if (!(pa->str= (uchar*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD), - MYF(MY_WME)))) + if (!(pa->str= (uchar*) my_malloc(PS_MALLOC - MALLOC_OVERHEAD, + MYF(MY_WME)))) { my_free(pa->typelib.type_names); DBUG_RETURN (-1); @@ -10955,9 +11034,8 @@ int insert_pointer_name(POINTER_ARRAY *pa,char * name) length=(uint) strlen(name)+1; if (pa->length+length >= pa->max_length) { - if (!(new_pos= (uchar*) my_realloc((uchar*) pa->str, - (uint) (pa->length+length+PS_MALLOC), - MYF(MY_WME)))) + if (!(new_pos= (uchar*) my_realloc(pa->str, pa->length + length + PS_MALLOC, + MYF(MY_WME)))) DBUG_RETURN(1); if (new_pos != pa->str) { @@ -10974,8 +11052,8 @@ int insert_pointer_name(POINTER_ARRAY *pa,char * name) int len; pa->array_allocs++; len=(PC_MALLOC*pa->array_allocs - MALLOC_OVERHEAD); - if (!(new_array=(const char **) my_realloc((uchar*) pa->typelib.type_names, - (uint) len/ + if (!(new_array=(const char **) my_realloc(pa->typelib.type_names, + len/ (sizeof(uchar*)+sizeof(*pa->flag))* (sizeof(uchar*)+sizeof(*pa->flag)), MYF(MY_WME)))) @@ -10984,13 +11062,13 @@ int insert_pointer_name(POINTER_ARRAY *pa,char * name) old_count=pa->max_count; pa->max_count=len/(sizeof(uchar*) + sizeof(*pa->flag)); pa->flag= (uint8*) (pa->typelib.type_names+pa->max_count); - memcpy((uchar*) pa->flag,(char *) (pa->typelib.type_names+old_count), + memcpy(pa->flag, (pa->typelib.type_names +old_count), old_count*sizeof(*pa->flag)); } pa->flag[pa->typelib.count]=0; /* Reset flag */ pa->typelib.type_names[pa->typelib.count++]= (char*) pa->str+pa->length; pa->typelib.type_names[pa->typelib.count]= NullS; /* Put end-mark */ - (void) strmov((char*) pa->str+pa->length,name); + (void) strmov((char*) pa->str + pa->length,name); pa->length+=length; DBUG_RETURN(0); } /* insert_pointer_name */ @@ -11013,22 +11091,24 @@ void free_pointer_array(POINTER_ARRAY *pa) /* Functions that uses replace and replace_regex */ /* Append the string to ds, with optional replace */ -void replace_dynstr_append_mem(DYNAMIC_STRING *ds, - const char *val, size_t len) +void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, size_t len) { - char lower[512]; -#ifdef __WIN__ - fix_win_paths(val, len); -#endif + char lower[1024]; - if (display_result_lower) + if (len < sizeof(lower) - 1) { - /* Convert to lower case, and do this first */ - char *c= lower; - for (const char *v= val; *v; v++) - *c++= my_tolower(charset_info, *v); - *c= '\0'; - /* Copy from this buffer instead */ + if (display_result_lower) + { + /* Convert to lower case, and do this first */ + char *c= lower; + for (const char *v= val; *v; v++) + *c++= my_tolower(charset_info, *v); + *c= '\0'; + /* Copy from this buffer instead */ + } + else + memcpy(lower, val, len+1); + fix_win_paths(lower, len); val= lower; } @@ -11117,7 +11197,7 @@ void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input, *line_end= 0; /* Insert pointer to the line in array */ - if (insert_dynamic(&lines, (uchar*) &start)) + if (insert_dynamic(&lines, &start)) die("Out of memory inserting lines to sort"); start= line_end+1; |