diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/async_example.c | 4 | ||||
-rw-r--r-- | client/client_priv.h | 70 | ||||
-rw-r--r-- | client/mariadb-conv.cc | 11 | ||||
-rw-r--r-- | client/mysql.cc | 226 | ||||
-rw-r--r-- | client/mysql_plugin.c | 10 | ||||
-rw-r--r-- | client/mysql_upgrade.c | 8 | ||||
-rw-r--r-- | client/mysqladmin.cc | 172 | ||||
-rw-r--r-- | client/mysqlbinlog.cc | 95 | ||||
-rw-r--r-- | client/mysqlcheck.c | 75 | ||||
-rw-r--r-- | client/mysqldump.c | 97 | ||||
-rw-r--r-- | client/mysqlimport.c | 71 | ||||
-rw-r--r-- | client/mysqlshow.c | 71 | ||||
-rw-r--r-- | client/mysqlslap.c | 78 | ||||
-rw-r--r-- | client/mysqltest.cc | 298 | ||||
-rw-r--r-- | client/readline.cc | 2 |
15 files changed, 962 insertions, 326 deletions
diff --git a/client/async_example.c b/client/async_example.c index ccb60950904..f216de22930 100644 --- a/client/async_example.c +++ b/client/async_example.c @@ -16,7 +16,7 @@ */ -#ifndef __WIN__ +#ifndef _WIN32 #include <poll.h> #else #include <WinSock2.h> @@ -33,7 +33,7 @@ static const char *my_groups[]= { "client", NULL }; static int wait_for_mysql(MYSQL *mysql, int status) { -#ifdef __WIN__ +#ifdef _WIN32 fd_set rs, ws, es; int res; struct timeval tv, *timeout; diff --git a/client/client_priv.h b/client/client_priv.h index 16547494d03..56e81ebb94f 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -27,7 +27,7 @@ #include <mysql_version.h> #ifndef WEXITSTATUS -# ifdef __WIN__ +# ifdef _WIN32 # define WEXITSTATUS(stat_val) (stat_val) # else # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) @@ -128,3 +128,71 @@ enum options_client Name of the performance schema database. */ #define PERFORMANCE_SCHEMA_DB_NAME "performance_schema" + +/** + First mariadb version supporting the sys schema. +*/ +#define FIRST_SYS_SCHEMA_VERSION 100600 + +/** + Name of the sys schema database. +*/ +#define SYS_SCHEMA_DB_NAME "sys" + +/** + The --socket CLI option has different meanings + across different operating systems. + */ +#ifndef _WIN32 +#define SOCKET_PROTOCOL_TO_FORCE MYSQL_PROTOCOL_SOCKET +#else +#define SOCKET_PROTOCOL_TO_FORCE MYSQL_PROTOCOL_PIPE +#endif + +/** + Utility function to implicitly change the connection protocol to a + consistent value given the command line arguments. Additionally, + warns the user that the protocol has been changed. + + Arguments: + @param [in] host Name of the host to connect to + @param [in, out] opt_protocol Location of the protocol option + variable to update + @param [in] new_protocol New protocol to force +*/ +static inline void warn_protocol_override(char *host, + uint *opt_protocol, + uint new_protocol) +{ + DBUG_ASSERT(new_protocol == MYSQL_PROTOCOL_TCP + || new_protocol == SOCKET_PROTOCOL_TO_FORCE); + + + if ((host == NULL + || strncmp(host, LOCAL_HOST, sizeof(LOCAL_HOST)-1) == 0)) + { + const char *protocol_name; + + if (*opt_protocol == MYSQL_PROTOCOL_DEFAULT +#ifndef _WIN32 + && new_protocol == MYSQL_PROTOCOL_SOCKET +#else + && new_protocol == MYSQL_PROTOCOL_TCP +#endif + ) + { + /* This is already the default behavior, do nothing */ + return; + } + + protocol_name= sql_protocol_typelib.type_names[new_protocol-1]; + + fprintf(stderr, "%s %s %s\n", + "WARNING: Forcing protocol to ", + protocol_name, + " due to option specification. " + "Please explicitly state intended protocol."); + + *opt_protocol = new_protocol; + } +} diff --git a/client/mariadb-conv.cc b/client/mariadb-conv.cc index 835c6a2abe2..1774debe5f9 100644 --- a/client/mariadb-conv.cc +++ b/client/mariadb-conv.cc @@ -43,7 +43,7 @@ public: { } static CHARSET_INFO *csinfo_by_name(const char *csname) { - return get_charset_by_csname(csname, MY_CS_PRIMARY, MYF(0)); + return get_charset_by_csname(csname, MY_CS_PRIMARY, MYF(MY_UTF8_IS_UTF8MB3)); } CHARSET_INFO *csinfo_from() const { @@ -70,6 +70,9 @@ static struct my_option long_options[] = {"delimiter", 0, "Treat the specified characters as delimiters.", &opt.m_delimiter, &opt.m_delimiter, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"character-sets-dir", OPT_CHARSETS_DIR, + "Directory for character set files.", &charsets_dir, + &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -344,7 +347,7 @@ private: fflush(stdout); fprintf(stderr, "Illegal %s byte sequence at position %d\n", - m_fromcs->csname, + m_fromcs->cs_name.str, (uint) (well_formed_error_pos() - from)); } else if (cannot_convert_error_pos()) @@ -352,7 +355,7 @@ private: fflush(stdout); fprintf(stderr, "Conversion from %s to %s failed at position %d\n", - m_fromcs->csname, m_tocs->csname, + m_fromcs->cs_name.str, m_tocs->cs_name.str, (uint) (cannot_convert_error_pos() - from)); } } @@ -453,7 +456,7 @@ int main(int argc, char *argv[]) charset_info_to->mbminlen > 1) { fprintf(stderr, "--delimiter cannot be used with %s to %s conversion\n", - charset_info_from->csname, charset_info_to->csname); + charset_info_from->cs_name.str, charset_info_to->cs_name.str); return 1; } if (conv.set_delimiter_unescape(opt.m_delimiter)) diff --git a/client/mysql.cc b/client/mysql.cc index 697f4d54ab3..935dfd12643 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -88,7 +88,7 @@ extern "C" { #endif /* defined(HAVE_CURSES_H) && defined(HAVE_TERM_H) */ #undef bcmp // Fix problem with new readline -#if defined(__WIN__) +#if defined(_WIN32) #include <conio.h> #else # ifdef __APPLE__ @@ -210,6 +210,8 @@ static uint opt_protocol=0; static const char *opt_protocol_type= ""; static CHARSET_INFO *charset_info= &my_charset_latin1; +static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; + #include "sslopt-vars.h" const char *default_dbug_option="d:t:o,/tmp/mariadb.trace"; @@ -1166,6 +1168,9 @@ int main(int argc,char *argv[]) close(stdout_fileno_copy); /* Clean up dup(). */ } + /* We need to know if protocol-related options originate from CLI args */ + my_defaults_mark_files = TRUE; + load_defaults_or_exit("my", load_default_groups, &argc, &argv); defaults_argv=argv; if ((status.exit_status= get_options(argc, (char **) argv))) @@ -1175,6 +1180,14 @@ int main(int argc,char *argv[]) exit(status.exit_status); } + /* Command line options override configured protocol */ + if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT + && protocol_to_force != opt_protocol) + { + warn_protocol_override(current_host, &opt_protocol, protocol_to_force); + } + + if (status.batch && !status.line_buff && !(status.line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, stdin))) { @@ -1580,7 +1593,7 @@ static struct my_option my_long_options[] = {"password", 'p', "Password to use when connecting to server. If password is not given it's asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef __WIN__ +#ifdef _WIN32 {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif @@ -1724,8 +1737,11 @@ static void usage(int version) my_bool -get_one_option(const struct my_option *opt, const char *argument, const char *) +get_one_option(const struct my_option *opt, const char *argument, const char *filename) { + /* Track when protocol is set via CLI to not force port TCP protocol override */ + static my_bool ignore_protocol_override = FALSE; + switch(opt->id) { case OPT_CHARSETS_DIR: strmake_buf(mysql_charsets_dir, argument); @@ -1790,6 +1806,14 @@ get_one_option(const struct my_option *opt, const char *argument, const char *) opt->name)) <= 0) exit(1); #endif + + /* Specification of protocol via CLI trumps implicit overrides */ + if (filename[0] == '\0') + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + break; case OPT_SERVER_ARG: #ifdef EMBEDDED_LIBRARY @@ -1886,9 +1910,16 @@ get_one_option(const struct my_option *opt, const char *argument, const char *) set_if_bigger(opt_silent,1); // more silent break; case 'W': -#ifdef __WIN__ +#ifdef _WIN32 opt_protocol = MYSQL_PROTOCOL_PIPE; opt_protocol_type= "pipe"; + + /* Prioritize pipe if explicit via command line */ + if (filename[0] == '\0') + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } #endif break; #include <sslopt-case.h> @@ -1900,6 +1931,38 @@ get_one_option(const struct my_option *opt, const char *argument, const char *) status.exit_status= 0; mysql_end(-1); break; + case 'P': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* If port is set via CLI, try to force protocol to TCP */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = MYSQL_PROTOCOL_TCP; + } + break; + case 'S': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == MYSQL_PROTOCOL_TCP) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* Prioritize socket if set via command line */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + } + break; case 'I': case '?': usage(0); @@ -1980,7 +2043,7 @@ static int get_options(int argc, char **argv) static int read_and_execute(bool interactive) { -#if defined(__WIN__) +#if defined(_WIN32) String tmpbuf; String buffer; #endif @@ -2016,13 +2079,14 @@ static int read_and_execute(bool interactive) { status.exit_status= 1; String msg; - msg.append("ASCII '\\0' appeared in the statement, but this is not " - "allowed unless option --binary-mode is enabled and mysql is " - "run in non-interactive mode. Set --binary-mode to 1 if ASCII " - "'\\0' is expected. Query: '"); + msg.append(STRING_WITH_LEN( + "ASCII '\\0' appeared in the statement, but this is not " + "allowed unless option --binary-mode is enabled and mysql is " + "run in non-interactive mode. Set --binary-mode to 1 if ASCII " + "'\\0' is expected. Query: '")); msg.append(glob_buffer); - msg.append(line); - msg.append("'."); + msg.append(line, strlen(line)); + msg.append(STRING_WITH_LEN("'.")); put_info(msg.c_ptr(), INFO_ERROR); break; } @@ -2059,7 +2123,7 @@ static int read_and_execute(bool interactive) if (opt_outfile && glob_buffer.is_empty()) fflush(OUTFILE); -#if defined(__WIN__) +#if defined(_WIN32) tee_fputs(prompt, stdout); if (!tmpbuf.is_alloced()) tmpbuf.alloc(65535); @@ -2092,7 +2156,7 @@ static int read_and_execute(bool interactive) if (line) free(line); line= readline(prompt); -#endif /* defined(__WIN__) */ +#endif /* defined(_WIN32) */ /* When Ctrl+d or Ctrl+z is pressed, the line may be NULL on some OS @@ -2147,7 +2211,7 @@ static int read_and_execute(bool interactive) } } -#if defined(__WIN__) +#if defined(_WIN32) buffer.free(); tmpbuf.free(); #else @@ -2423,8 +2487,9 @@ static bool add_line(String &buffer, char *line, size_t line_length, my_isspace(charset_info, pos[2])))) { // Add trailing single line comments to this statement - buffer.append(pos); - pos+= strlen(pos); + size_t length= strlen(pos); + buffer.append(pos, length); + pos+= length; } pos--; @@ -2470,7 +2535,7 @@ static bool add_line(String &buffer, char *line, size_t line_length, { bool started_with_nothing= !buffer.length(); - buffer.append(pos); + buffer.append(pos, strlen(pos)); /* A single-line comment by itself gets sent immediately so that @@ -2628,7 +2693,7 @@ static void fix_history(String *final_command) not in string, change to space if in string, leave it alone */ - fixed_buffer.append(str_char == '\0' ? " " : "\n"); + fixed_buffer.append(str_char == '\0' ? ' ' : '\n'); total_lines++; break; case '\\': @@ -3200,12 +3265,13 @@ com_charset(String *buffer __attribute__((unused)), char *line) return put_info("Usage: \\C charset_name | charset charset_name", INFO_ERROR, 0); } - new_cs= get_charset_by_csname(param, MY_CS_PRIMARY, MYF(MY_WME)); + new_cs= get_charset_by_csname(param, MY_CS_PRIMARY, + MYF(MY_UTF8_IS_UTF8MB3 | MY_WME)); if (new_cs) { charset_info= new_cs; - mysql_set_character_set(&mysql, charset_info->csname); - default_charset= (char *)charset_info->csname; + mysql_set_character_set(&mysql, charset_info->cs_name.str); + default_charset= (char *)charset_info->cs_name.str; put_info("Charset changed", INFO_INFO); } else put_info("Charset is not found", INFO_INFO); @@ -3273,7 +3339,8 @@ com_go(String *buffer,char *line __attribute__((unused))) #ifdef HAVE_READLINE if (status.add_to_history) { - buffer->append(vertical ? "\\G" : delimiter); + const char *delim= vertical ? "\\G" : delimiter; + buffer->append(delim, strlen(delim)); /* Append final command onto history */ fix_history(buffer); } @@ -4688,6 +4755,8 @@ static int sql_real_connect(char *host,char *database,char *user,char *password, uint silent) { + const char *charset_name; + if (connected) { connected= 0; @@ -4735,13 +4804,17 @@ sql_real_connect(char *host,char *database,char *user,char *password, return -1; // Retryable } - if (!(charset_info= get_charset_by_name(mysql.charset->name, MYF(0)))) + charset_name= IF_EMBEDDED(mysql.charset->coll_name.str, + mysql.charset->name); + charset_info= get_charset_by_name(charset_name, MYF(MY_UTF8_IS_UTF8MB3)); + if (!charset_info) { - put_info("Unknown default character set", INFO_ERROR); + char buff[128]; + my_snprintf(buff, sizeof(buff)-1, + "Unknown default character set %s", charset_name); + put_info(buff, INFO_ERROR); return 1; } - - connected=1; #ifndef EMBEDDED_LIBRARY mysql_options(&mysql, MYSQL_OPT_RECONNECT, &debug_info_flag); @@ -4880,8 +4953,9 @@ com_status(String *buffer __attribute__((unused)), else { /* Probably pre-4.1 server */ - tee_fprintf(stdout, "Client characterset:\t%s\n", charset_info->csname); - tee_fprintf(stdout, "Server characterset:\t%s\n", mysql.charset->csname); + tee_fprintf(stdout, "Client characterset:\t%s\n", charset_info->cs_name.str); + tee_fprintf(stdout, "Server characterset:\t%s\n", + mysql_character_set_name(&mysql)); } #ifndef EMBEDDED_LIBRARY @@ -5182,20 +5256,27 @@ static const char *construct_prompt() add_int_to_prompt(++prompt_counter); break; case 'v': - if (connected) - processed_prompt.append(mysql_get_server_info(&mysql)); - else - processed_prompt.append("not_connected"); + { + const char *info= (connected ? + mysql_get_server_info(&mysql) : + "not_connected"); + processed_prompt.append(info, strlen(info)); break; + } case 'd': - processed_prompt.append(current_db ? current_db : "(none)"); - break; + { + const char *db= current_db ? current_db : "(none)"; + processed_prompt.append(db, strlen(db)); + break; + } case 'N': - if (connected) - processed_prompt.append(mysql_get_server_name(&mysql)); - else - processed_prompt.append("unknown"); + { + const char *name= (connected ? + mysql_get_server_name(&mysql) : + "unknown"); + processed_prompt.append(name, strlen(name)); break; + } case 'h': case 'H': { @@ -5204,16 +5285,20 @@ static const char *construct_prompt() if (strstr(prompt, "Localhost") || strstr(prompt, "localhost ")) { if (*c == 'h') - processed_prompt.append("localhost"); + processed_prompt.append(STRING_WITH_LEN("localhost")); else { static char hostname[FN_REFLEN]; - if (hostname[0]) - processed_prompt.append(hostname); + static size_t hostname_length; + if (hostname_length) + processed_prompt.append(hostname, hostname_length); else if (gethostname(hostname, sizeof(hostname)) == 0) - processed_prompt.append(hostname); + { + hostname_length= strlen(hostname); + processed_prompt.append(hostname, hostname_length); + } else - processed_prompt.append("gethostname(2) failed"); + processed_prompt.append(STRING_WITH_LEN("gethostname(2) failed")); } } else @@ -5228,38 +5313,47 @@ static const char *construct_prompt() #ifndef EMBEDDED_LIBRARY if (!connected) { - processed_prompt.append("not_connected"); + processed_prompt.append(STRING_WITH_LEN("not_connected")); break; } const char *host_info = mysql_get_host_info(&mysql); if (strstr(host_info, "memory")) { - processed_prompt.append( mysql.host ); + processed_prompt.append( mysql.host, strlen(mysql.host)); } else if (strstr(host_info,"TCP/IP") || !mysql.unix_socket) add_int_to_prompt(mysql.port); else { - char *pos=strrchr(mysql.unix_socket,'/'); - processed_prompt.append(pos ? pos+1 : mysql.unix_socket); + char *pos= strrchr(mysql.unix_socket,'/'); + const char *tmp= pos ? pos+1 : mysql.unix_socket; + processed_prompt.append(tmp, strlen(tmp)); } #endif } break; case 'U': + { + const char *name; if (!full_username) init_username(); - processed_prompt.append(full_username ? full_username : - (current_user ? current_user : "(unknown)")); + name= (full_username ? full_username : + (current_user ? current_user : "(unknown)")); + processed_prompt.append(name, strlen(name)); break; + } case 'u': + { + const char *name; if (!full_username) init_username(); - processed_prompt.append(part_username ? part_username : - (current_user ? current_user : "(unknown)")); + name= (part_username ? part_username : + (current_user ? current_user : "(unknown)")); + processed_prompt.append(name, strlen(name)); break; + } case PROMPT_CHAR: processed_prompt.append(PROMPT_CHAR); break; @@ -5300,29 +5394,39 @@ static const char *construct_prompt() add_int_to_prompt(t->tm_year+1900); break; case 'D': + { char* dateTime; + const char *tmp; dateTime = ctime(&lclock); - processed_prompt.append(strtok(dateTime,"\n")); + tmp= strtok(dateTime,"\n"); + processed_prompt.append(tmp, strlen(tmp)); break; + } case 's': if (t->tm_sec < 10) processed_prompt.append('0'); add_int_to_prompt(t->tm_sec); break; case 'w': - processed_prompt.append(day_names[t->tm_wday]); - break; + { + const char *name= day_names[t->tm_wday]; + processed_prompt.append(name, strlen(name)); + break; + } case 'P': - processed_prompt.append(t->tm_hour < 12 ? "am" : "pm"); + processed_prompt.append(t->tm_hour < 12 ? "am" : "pm", 2); break; case 'o': add_int_to_prompt(t->tm_mon+1); break; case 'O': - processed_prompt.append(month_names[t->tm_mon]); + { + const char *name= month_names[t->tm_mon]; + processed_prompt.append(name, strlen(name)); break; + } case '\'': - processed_prompt.append("'"); + processed_prompt.append('\''); break; case '"': processed_prompt.append('"'); @@ -5334,10 +5438,10 @@ static const char *construct_prompt() processed_prompt.append('\t'); break; case 'l': - processed_prompt.append(delimiter_str); + processed_prompt.append(delimiter_str, strlen(delimiter_str)); break; default: - processed_prompt.append(c); + processed_prompt.append(*c); } } } @@ -5349,8 +5453,8 @@ static const char *construct_prompt() static void add_int_to_prompt(int toadd) { char buffer[16]; - int10_to_str(toadd,buffer,10); - processed_prompt.append(buffer); + size_t length= (size_t) (int10_to_str(toadd,buffer,10) - buffer); + processed_prompt.append(buffer, length); } static void init_username() diff --git a/client/mysql_plugin.c b/client/mysql_plugin.c index a00f5e4450b..d9084ec7c35 100644 --- a/client/mysql_plugin.c +++ b/client/mysql_plugin.c @@ -235,7 +235,7 @@ static int run_command(char* cmd, const char *mode) } -#ifdef __WIN__ +#ifdef _WIN32 /** Check to see if there are spaces in a path. @@ -332,7 +332,7 @@ static int get_default_values() if ((error= make_tempfile(defaults_file, "txt"))) goto exit; -#ifdef __WIN__ +#ifdef _WIN32 { char *format_str= 0; @@ -878,7 +878,7 @@ static int process_options(int argc, char *argv[], char *operation) memset(buff, 0, sizeof(buff)); strncpy(buff, opt_basedir, sizeof(buff) - 1); -#ifdef __WIN__ +#ifdef _WIN32 strncat(buff, "/", sizeof(buff) - strlen(buff) - 1); #else strncat(buff, FN_DIRSEP, sizeof(buff) - strlen(buff) - 1); @@ -967,7 +967,7 @@ static int check_access() } if (opt_mysqld && (error= my_access(opt_mysqld, F_OK))) { - fprintf(stderr, "ERROR: Cannot access mysqld path '%s'.\n", + fprintf(stderr, "ERROR: Cannot access mariadbd path '%s'.\n", opt_mysqld); goto exit; } @@ -1201,7 +1201,7 @@ static int bootstrap_server(char *server_path, char *bootstrap_file) char bootstrap_cmd[FN_REFLEN]; int error= 0; -#ifdef __WIN__ +#ifdef _WIN32 char *format_str= 0; const char *verbose_str= NULL; diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 4e7ddec312f..b35d9e90ffd 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -29,7 +29,7 @@ #endif #ifndef WEXITSTATUS -# ifdef __WIN__ +# ifdef _WIN32 # define WEXITSTATUS(stat_val) (stat_val) # else # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) @@ -126,7 +126,7 @@ static struct my_option my_long_options[]= "Password to use when connecting to server. If password is not given," " it's solicited on the tty.", &opt_password,&opt_password, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef __WIN__ +#ifdef _WIN32 {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif @@ -487,7 +487,7 @@ static int run_tool(char *tool_path, DYNAMIC_STRING *ds_res, ...) va_end(args); -#ifdef __WIN__ +#ifdef _WIN32 dynstr_append(&ds_cmdline, "\""); #endif @@ -1411,7 +1411,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 defined(__WIN__) +#if defined(_WIN32) if (GetModuleFileName(NULL, self_name, FN_REFLEN) == 0) #endif { diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 85043f03b53..b30cf8e8b2c 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -54,6 +54,8 @@ static bool sql_log_bin_off= false; static uint opt_protocol=0; static myf error_flags; /* flags to pass to my_printf_error, like ME_BELL */ +static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; + /* When using extended-status relatively, ex_val_max_len is the estimated maximum length for any relative value printed by extended-status. The @@ -109,7 +111,7 @@ enum commands { ADMIN_FLUSH_TABLE_STATISTICS, ADMIN_FLUSH_INDEX_STATISTICS, ADMIN_FLUSH_USER_STATISTICS, ADMIN_FLUSH_CLIENT_STATISTICS, ADMIN_FLUSH_USER_RESOURCES, - ADMIN_FLUSH_ALL_STATUS, ADMIN_FLUSH_ALL_STATISTICS + ADMIN_FLUSH_ALL_STATUS, ADMIN_FLUSH_ALL_STATISTICS, ADMIN_FLUSH_SSL }; static const char *command_names[]= { "create", "drop", "shutdown", @@ -124,7 +126,7 @@ static const char *command_names[]= { "flush-error-log", "flush-general-log", "flush-relay-log", "flush-slow-log", "flush-table-statistics", "flush-index-statistics", "flush-user-statistics", "flush-client-statistics", "flush-user-resources", - "flush-all-status", "flush-all-statistics", + "flush-all-status", "flush-all-statistics", "flush-ssl", NullS }; @@ -173,7 +175,7 @@ static struct my_option my_long_options[] = {"password", 'p', "Password to use when connecting to server. If password is not given it's asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef __WIN__ +#ifdef _WIN32 {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif @@ -241,8 +243,12 @@ static const char *load_default_groups[]= 0 }; my_bool -get_one_option(const struct my_option *opt, const char *argument, const char *) +get_one_option(const struct my_option *opt, const char *argument, const char *filename) { + + /* Track when protocol is set via CLI to not force overrides */ + static my_bool ignore_protocol_override = FALSE; + switch(opt->id) { case 'c': opt_count_iterations= 1; @@ -272,8 +278,15 @@ get_one_option(const struct my_option *opt, const char *argument, const char *) option_silent++; break; case 'W': -#ifdef __WIN__ +#ifdef _WIN32 opt_protocol = MYSQL_PROTOCOL_PIPE; + + /* Prioritize pipe if explicit via command line */ + if (filename[0] == '\0') + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } #endif break; case '#': @@ -309,6 +322,46 @@ get_one_option(const struct my_option *opt, const char *argument, const char *) sf_leaking_memory= 1; /* no memory leak reports here */ exit(1); } + + /* Specification of protocol via CLI trumps implicit overrides */ + if (filename[0] == '\0') + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + break; + case 'P': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* If port is set via CLI, try to force protocol to TCP */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = MYSQL_PROTOCOL_TCP; + } + break; + case 'S': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == MYSQL_PROTOCOL_TCP) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* Prioritize socket if set via command line */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + } break; } return 0; @@ -323,6 +376,10 @@ int main(int argc,char *argv[]) MY_INIT(argv[0]); sf_leaking_memory=1; /* don't report memory leaks on early exits */ + + /* We need to know if protocol-related options originate from CLI args */ + my_defaults_mark_files = TRUE; + load_defaults_or_exit("my", load_default_groups, &argc, &argv); save_argv = argv; /* Save for free_defaults */ @@ -331,6 +388,13 @@ int main(int argc,char *argv[]) temp_argv= mask_password(argc, &argv); temp_argc= argc; + /* Command line options override configured protocol */ + if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT + && protocol_to_force != opt_protocol) + { + warn_protocol_override(host, &opt_protocol, protocol_to_force); + } + if (debug_info_flag) my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; if (debug_check_flag) @@ -552,13 +616,13 @@ static my_bool sql_connect(MYSQL *mysql, uint wait) if (mysql_errno(mysql) == CR_CONNECTION_ERROR) { fprintf(stderr, - "Check that mysqld is running and that the socket: '%s' exists!\n", + "Check that mariadbd is running and that the socket: '%s' exists!\n", unix_port ? unix_port : mysql_unix_port); } else if (mysql_errno(mysql) == CR_CONN_HOST_ERROR || mysql_errno(mysql) == CR_UNKNOWN_HOST) { - fprintf(stderr,"Check that mysqld is running on %s",host); + fprintf(stderr,"Check that mariadbd is running on %s",host); fprintf(stderr," and that the port is %d.\n", tcp_port ? tcp_port: mysql_port); fprintf(stderr,"You can check this by doing 'telnet %s %d'\n", @@ -623,7 +687,14 @@ int flush(MYSQL *mysql, const char *what) char buf[FN_REFLEN]; my_snprintf(buf, sizeof(buf), "flush %s%s", (opt_local && !sql_log_bin_off ? "local " : ""), what); - return mysql_query(mysql, buf); + + if (mysql_query(mysql, buf)) + { + my_printf_error(0, "flush %s failed; error: '%s'", error_flags, what, + mysql_error(mysql)); + return -1; + } + return 0; } @@ -739,11 +810,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) case ADMIN_FLUSH_PRIVILEGES: case ADMIN_RELOAD: if (flush(mysql, "privileges")) - { - my_printf_error(0, "reload failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; case ADMIN_REFRESH: if (mysql_refresh(mysql, @@ -943,173 +1010,111 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) case ADMIN_FLUSH_LOGS: { if (flush(mysql, "logs")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_FLUSH_BINARY_LOG: { if (flush(mysql, "binary logs")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_FLUSH_ENGINE_LOG: { if (flush(mysql, "engine logs")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_FLUSH_ERROR_LOG: { if (flush(mysql, "error logs")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_FLUSH_GENERAL_LOG: { if (flush(mysql, "general logs")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_FLUSH_RELAY_LOG: { if (flush(mysql, "relay logs")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_FLUSH_SLOW_LOG: { if (flush(mysql, "slow logs")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_FLUSH_HOSTS: { if (flush(mysql, "hosts")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_FLUSH_TABLES: { if (flush(mysql, "tables")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_FLUSH_STATUS: { if (flush(mysql, "status")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_FLUSH_TABLE_STATISTICS: { if (flush(mysql, "table_statistics")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_FLUSH_INDEX_STATISTICS: { if (flush(mysql, "index_statistics")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } + break; + } + case ADMIN_FLUSH_SSL: + { + if (flush(mysql, "ssl")) + return -1; break; } case ADMIN_FLUSH_USER_STATISTICS: { if (flush(mysql, "user_statistics")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_FLUSH_USER_RESOURCES: { if (flush(mysql, "user_resources")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_FLUSH_CLIENT_STATISTICS: { if (flush(mysql, "client_statistics")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_FLUSH_ALL_STATISTICS: { if (flush(mysql, "table_statistics,index_statistics," "user_statistics,client_statistics")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_FLUSH_ALL_STATUS: { if (flush(mysql, "status,table_statistics,index_statistics," "user_statistics,client_statistics")) - { - my_printf_error(0, "flush failed; error: '%s'", error_flags, - mysql_error(mysql)); return -1; - } break; } case ADMIN_OLD_PASSWORD: @@ -1148,7 +1153,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { bool old= (find_type(argv[0], &command_typelib, FIND_TYPE_BASIC) == ADMIN_OLD_PASSWORD); -#ifdef __WIN__ +#ifdef _WIN32 size_t pw_len= strlen(typed_password); if (pw_len > 1 && typed_password[0] == '\'' && typed_password[pw_len-1] == '\'') @@ -1220,7 +1225,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) because we can't perfectly find out the host */ my_printf_error(0,"\n" - "You cannot use 'password' command as mysqld runs\n" + "You cannot use 'password' command as mariadbd runs\n" " with grant tables disabled (was started with" " --skip-grant-tables).\n" "Use: \"mysqladmin flush-privileges password '*'\"" @@ -1321,7 +1326,7 @@ password_done: } else { - my_printf_error(0,"mysqld doesn't answer to ping, error: '%s'", + my_printf_error(0,"mariadbd doesn't answer to ping, error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -1418,6 +1423,7 @@ static void usage(void) flush-general-log Flush general log\n\ flush-relay-log Flush relay log\n\ flush-slow-log Flush slow query log\n\ + flush-ssl Flush SSL certificates\n\ flush-status Clear status variables\n\ flush-table-statistics Clear table statistics\n\ flush-tables Flush all tables\n\ diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 4084ff33623..cc38a310e5d 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -98,6 +98,8 @@ static const char *output_prefix= ""; static char **defaults_argv= 0; static MEM_ROOT glob_root; +static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; + #ifndef DBUG_OFF static const char *default_dbug_option = "d:t:o,/tmp/mariadb-binlog.trace"; const char *current_dbug_option= default_dbug_option; @@ -214,7 +216,7 @@ Log_event* read_remote_annotate_event(uchar* net_buf, ulong event_len, memcpy(event_buf, net_buf, event_len); event_buf[event_len]= 0; - if (!(event= Log_event::read_log_event((const char*) event_buf, event_len, + if (!(event= Log_event::read_log_event(event_buf, event_len, error_msg, glob_description_event, opt_verify_binlog_checksum))) { @@ -225,7 +227,7 @@ Log_event* read_remote_annotate_event(uchar* net_buf, ulong event_len, Ensure the event->temp_buf is pointing to the allocated buffer. (TRUE = free temp_buf on the event deletion) */ - event->register_temp_buf((char*)event_buf, TRUE); + event->register_temp_buf(event_buf, TRUE); return event; } @@ -510,8 +512,7 @@ Exit_status Load_log_processor::load_old_format_file(NET* net, error("Illegal length of packet read from net."); return ERROR_STOP; } - if (my_write(file, (uchar*) net->read_pos, - (uint) packet_len, MYF(MY_WME|MY_NABP))) + if (my_write(file, net->read_pos, (uint) packet_len, MYF(MY_WME|MY_NABP))) return ERROR_STOP; } @@ -1201,7 +1202,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, (glob_description_event->flags & LOG_EVENT_BINLOG_IN_USE_F)) { error("Attempting to dump binlog '%s', which was not closed properly. " - "Most probably, mysqld is still writing it, or it crashed. " + "Most probably, mariadbd is still writing it, or it crashed. " "Rerun with --force-if-open to ignore this problem.", logname); DBUG_RETURN(ERROR_STOP); } @@ -1514,14 +1515,16 @@ 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' doesn't print binlog row events and should not be " - "used when directing output to a MariaDB master; " + "statements: " + "‘never’ neither prints base64 encodings nor verbose event data, and " + "will exit on error if a row-based event is found. " "'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); " - "If no --base64-output=name option is given at all, the default is " - "'auto'.", + "--verbose option is also given. " + "‘auto’ outputs base64 encoded entries for row-based and format " + "description events. " + "If no option is given at all, the default is ‘auto', and is " + "consequently the only option that should be used when row-format events " + "are processed for re-execution.", &opt_base64_output_mode_str, &opt_base64_output_mode_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, /* @@ -1890,9 +1893,13 @@ static my_time_t convert_str_to_timestamp(const char* str) extern "C" my_bool -get_one_option(const struct my_option *opt, const char *argument, const char *) +get_one_option(const struct my_option *opt, const char *argument, const char *filename) { bool tty_password=0; + + /* Track when protocol is set via CLI to not force overrides */ + static my_bool ignore_protocol_override = FALSE; + switch (opt->id) { #ifndef DBUG_OFF case '#': @@ -1942,6 +1949,14 @@ get_one_option(const struct my_option *opt, const char *argument, const char *) sf_leaking_memory= 1; /* no memory leak reports here */ die(); } + + /* Specification of protocol via CLI trumps implicit overrides */ + if (filename[0] == '\0') + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + break; #ifdef WHEN_FLASHBACK_REVIEW_READY case opt_flashback_review: @@ -2018,6 +2033,38 @@ get_one_option(const struct my_option *opt, const char *argument, const char *) case OPT_PRINT_ROW_EVENT_POSITIONS: print_row_event_positions_used= 1; break; + case 'P': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* If port is set via CLI, try to force protocol to TCP */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = MYSQL_PROTOCOL_TCP; + } + break; + case 'S': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == MYSQL_PROTOCOL_TCP) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* Prioritize socket if set via command line */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + } + break; case 'v': if (argument == disabled_my_option) verbose= 0; @@ -2302,7 +2349,7 @@ static Exit_status handle_event_text_mode(PRINT_EVENT_INFO *print_event_info, } else { - if (!(ev= Log_event::read_log_event((const char*) net->read_pos + 1 , + if (!(ev= Log_event::read_log_event(net->read_pos + 1 , *len - 1, &error_msg, glob_description_event, opt_verify_binlog_checksum))) @@ -2314,7 +2361,7 @@ static Exit_status handle_event_text_mode(PRINT_EVENT_INFO *print_event_info, If reading from a remote host, ensure the temp_buf for the Log_event class is pointing to the incoming stream. */ - ev->register_temp_buf((char *) net->read_pos + 1, FALSE); + ev->register_temp_buf(net->read_pos + 1, FALSE); } Log_event_type type= ev->get_type_code(); @@ -2415,7 +2462,7 @@ static Exit_status handle_event_raw_mode(PRINT_EVENT_INFO *print_event_info, const char* logname, uint logname_len) { const char *error_msg; - const unsigned char *read_pos= mysql->net.read_pos + 1; + const uchar *read_pos= mysql->net.read_pos + 1; Log_event_type type; DBUG_ENTER("handle_event_raw_mode"); DBUG_ASSERT(opt_raw_mode && remote_opt); @@ -2428,7 +2475,7 @@ static Exit_status handle_event_raw_mode(PRINT_EVENT_INFO *print_event_info, if (type == ROTATE_EVENT || type == FORMAT_DESCRIPTION_EVENT) { Log_event *ev; - if (!(ev= Log_event::read_log_event((const char*) read_pos , + if (!(ev= Log_event::read_log_event(read_pos , *len - 1, &error_msg, glob_description_event, opt_verify_binlog_checksum))) @@ -2441,7 +2488,7 @@ static Exit_status handle_event_raw_mode(PRINT_EVENT_INFO *print_event_info, If reading from a remote host, ensure the temp_buf for the Log_event class is pointing to the incoming stream. */ - ev->register_temp_buf((char *) read_pos, FALSE); + ev->register_temp_buf(const_cast<uchar*>(read_pos), FALSE); if (type == ROTATE_EVENT) { @@ -2872,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__) || defined(_WIN64) +#if defined (_WIN32) if (_setmode(fileno(stdin), O_BINARY) == -1) { error("Could not set binary mode on stdin."); @@ -2975,6 +3022,9 @@ int main(int argc, char** argv) my_init_time(); // for time functions tzset(); // set tzname + /* We need to know if protocol-related options originate from CLI args */ + my_defaults_mark_files = TRUE; + load_defaults_or_exit("my", load_groups, &argc, &argv); defaults_argv= argv; @@ -2988,6 +3038,13 @@ int main(int argc, char** argv) parse_args(&argc, (char***)&argv); + /* Command line options override configured protocol */ + if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT + && protocol_to_force != opt_protocol) + { + warn_protocol_override(host, &opt_protocol, protocol_to_force); + } + if (!argc || opt_version) { if (!opt_version) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index bf70a097c09..45a828cb18c 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -57,6 +57,8 @@ DYNAMIC_ARRAY tables4repair, tables4rebuild, alter_table_cmds; DYNAMIC_ARRAY views4repair; static uint opt_protocol=0; +static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; + enum operations { DO_CHECK=1, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_FIX_NAMES }; const char *operation_name[]= { @@ -163,7 +165,7 @@ static struct my_option my_long_options[] = "When using ANALYZE TABLE use the PERSISTENT FOR ALL option.", &opt_persistent_all, &opt_persistent_all, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef __WIN__ +#ifdef _WIN32 {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif @@ -286,9 +288,13 @@ static void usage(void) static my_bool get_one_option(const struct my_option *opt, const char *argument, - const char *filename __attribute__((unused))) + const char *filename) { int orig_what_to_do= what_to_do; + + /* Track when protocol is set via CLI to not force overrides */ + static my_bool ignore_protocol_override = FALSE; + DBUG_ENTER("get_one_option"); switch(opt->id) { @@ -349,8 +355,15 @@ get_one_option(const struct my_option *opt, opt_upgrade= 1; break; case 'W': -#ifdef __WIN__ +#ifdef _WIN32 opt_protocol = MYSQL_PROTOCOL_PIPE; + + /* Prioritize pipe if explicit via command line */ + if (filename[0] == '\0') + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } #endif break; case '#': @@ -374,6 +387,46 @@ get_one_option(const struct my_option *opt, sf_leaking_memory= 1; /* no memory leak reports here */ exit(1); } + + /* Specification of protocol via CLI trumps implicit overrides */ + if (filename[0] == '\0') + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + break; + case 'P': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* If port is set via CLI, try to force protocol to TCP */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = MYSQL_PROTOCOL_TCP; + } + break; + case 'S': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == MYSQL_PROTOCOL_TCP) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* Prioritize socket if set via command line */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + } break; } @@ -444,7 +497,8 @@ static int get_options(int *argc, char ***argv) if (!strcmp(default_charset, MYSQL_AUTODETECT_CHARSET_NAME)) default_charset= (char *)my_default_csname(); - if (!get_charset_by_csname(default_charset, MY_CS_PRIMARY, MYF(MY_WME))) + if (!get_charset_by_csname(default_charset, MY_CS_PRIMARY, + MYF(MY_UTF8_IS_UTF8MB3 | MY_WME))) { printf("Unsupported character set: %s\n", default_charset); DBUG_RETURN(1); @@ -1178,6 +1232,10 @@ int main(int argc, char **argv) MY_INIT(argv[0]); sf_leaking_memory=1; /* don't report memory leaks on early exits */ + + /* We need to know if protocol-related options originate from CLI args */ + my_defaults_mark_files = TRUE; + /* ** Check out the args */ @@ -1185,6 +1243,15 @@ int main(int argc, char **argv) defaults_argv= argv; if (get_options(&argc, &argv)) goto end1; + + + /* Command line options override configured protocol */ + if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT + && protocol_to_force != opt_protocol) + { + warn_protocol_override(current_host, &opt_protocol, protocol_to_force); + } + sf_leaking_memory=0; /* from now on we cleanup properly */ ret= EX_MYSQLERR; diff --git a/client/mysqldump.c b/client/mysqldump.c index e742519fa02..620ce211691 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -194,6 +194,8 @@ FILE *stderror_file=0; static uint opt_protocol= 0; static char *opt_plugin_dir= 0, *opt_default_auth= 0; +static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; + /* Dynamic_string wrapper functions. In this file use these wrappers, they will terminate the process if there is @@ -508,7 +510,7 @@ static struct my_option my_long_options[] = {"password", 'p', "Password to use when connecting to server. If password is not given it's solicited on the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef __WIN__ +#ifdef _WIN32 {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif @@ -866,8 +868,12 @@ uchar* get_table_key(const char *entry, size_t *length, static my_bool get_one_option(const struct my_option *opt, const char *argument, - const char *filename __attribute__((unused))) + const char *filename) { + + /* Track when protocol is set via CLI to not force overrides */ + static my_bool ignore_protocol_override = FALSE; + switch (opt->id) { case 'p': if (argument == disabled_my_option) @@ -896,8 +902,15 @@ get_one_option(const struct my_option *opt, exit(1); break; case 'W': -#ifdef __WIN__ +#ifdef _WIN32 opt_protocol= MYSQL_PROTOCOL_PIPE; + + /* Prioritize pipe if explicit via command line */ + if (filename[0] == '\0') + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } #endif break; case 'N': @@ -1048,11 +1061,51 @@ get_one_option(const struct my_option *opt, sf_leaking_memory= 1; /* no memory leak reports here */ exit(1); } + + /* Specification of protocol via CLI trumps implicit overrides */ + if (filename[0] == '\0') + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + break; case (int) OPT_DEFAULT_CHARSET: if (default_charset == disabled_my_option) default_charset= (char *)mysql_universal_client_charset; break; + case 'P': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* If port is set via CLI, try to force protocol to TCP */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = MYSQL_PROTOCOL_TCP; + } + break; + case 'S': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == MYSQL_PROTOCOL_TCP) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* Prioritize socket if set via command line */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + } + break; } return 0; } @@ -1065,6 +1118,9 @@ static int get_options(int *argc, char ***argv) opt_max_allowed_packet= *mysql_params->p_max_allowed_packet; opt_net_buffer_length= *mysql_params->p_net_buffer_length; + /* We need to know if protocol-related options originate from CLI args */ + my_defaults_mark_files = TRUE; + md_result_file= stdout; load_defaults_or_exit("my", load_default_groups, argc, argv); defaults_argv= *argv; @@ -1096,6 +1152,16 @@ static int get_options(int *argc, char ***argv) return(ho_error); /* + Command line options override configured protocol + */ + if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT + && protocol_to_force != opt_protocol) + { + warn_protocol_override(current_host, &opt_protocol, protocol_to_force); + } + + + /* Dumping under --system=stats with --replace or --insert-ignore is safe and will not result into race condition. Otherwise dump only structure and ignore data by default while dumping. @@ -1267,7 +1333,8 @@ static int get_options(int *argc, char ***argv) } if (strcmp(default_charset, MYSQL_AUTODETECT_CHARSET_NAME) && !(charset_info= get_charset_by_csname(default_charset, - MY_CS_PRIMARY, MYF(MY_WME)))) + MY_CS_PRIMARY, + MYF(MY_UTF8_IS_UTF8MB3 | MY_WME)))) exit(1); if ((*argc < 1 && (!opt_alldbs && !opt_system)) || (*argc > 0 && opt_alldbs)) { @@ -1578,7 +1645,7 @@ static int switch_db_collation(FILE *sql_file, char quoted_db_buf[NAME_LEN * 2 + 3]; char *quoted_db_name= quote_name(db_name, quoted_db_buf, FALSE); - CHARSET_INFO *db_cl= get_charset_by_name(required_db_cl_name, MYF(0)); + CHARSET_INFO *db_cl= get_charset_by_name(required_db_cl_name, MYF(MY_UTF8_IS_UTF8MB3)); if (!db_cl) return 1; @@ -1586,8 +1653,8 @@ static int switch_db_collation(FILE *sql_file, fprintf(sql_file, "ALTER DATABASE %s CHARACTER SET %s COLLATE %s %s\n", (const char *) quoted_db_name, - (const char *) db_cl->csname, - (const char *) db_cl->name, + (const char *) db_cl->cs_name.str, + (const char *) db_cl->coll_name.str, (const char *) delimiter); *db_cl_altered= 1; @@ -1609,7 +1676,7 @@ static int restore_db_collation(FILE *sql_file, char quoted_db_buf[NAME_LEN * 2 + 3]; char *quoted_db_name= quote_name(db_name, quoted_db_buf, FALSE); - CHARSET_INFO *db_cl= get_charset_by_name(db_cl_name, MYF(0)); + CHARSET_INFO *db_cl= get_charset_by_name(db_cl_name, MYF(MY_UTF8_IS_UTF8MB3)); if (!db_cl) return 1; @@ -1617,8 +1684,8 @@ static int restore_db_collation(FILE *sql_file, fprintf(sql_file, "ALTER DATABASE %s CHARACTER SET %s COLLATE %s %s\n", (const char *) quoted_db_name, - (const char *) db_cl->csname, - (const char *) db_cl->name, + (const char *) db_cl->cs_name.str, + (const char *) db_cl->coll_name.str, (const char *) delimiter); return 0; @@ -4037,7 +4104,7 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, dynstr_append_checked(&query_string, " /*!50138 CHARACTER SET "); dynstr_append_checked(&query_string, default_charset == mysql_universal_client_charset ? - my_charset_bin.name : /* backward compatibility */ + my_charset_bin.coll_name.str : /* backward compatibility */ default_charset); dynstr_append_checked(&query_string, " */"); @@ -5212,6 +5279,10 @@ static int dump_all_databases() !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME)) continue; + if (mysql_get_server_version(mysql) >= FIRST_SYS_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, row[0], SYS_SCHEMA_DB_NAME)) + continue; + if (include_database(row[0])) if (dump_all_tables_in_db(row[0])) result=1; @@ -5236,6 +5307,10 @@ static int dump_all_databases() !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME)) continue; + if (mysql_get_server_version(mysql) >= FIRST_SYS_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, row[0], SYS_SCHEMA_DB_NAME)) + continue; + if (include_database(row[0])) if (dump_all_views_in_db(row[0])) result=1; diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 6955ca44008..395b64d1119 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -63,6 +63,9 @@ static uint opt_mysql_port= 0, opt_protocol= 0; static char * opt_mysql_unix_port=0; static char *opt_plugin_dir= 0, *opt_default_auth= 0; static longlong opt_ignore_lines= -1; + +static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; + #include <sslopt-vars.h> static char **argv_to_free; @@ -143,7 +146,7 @@ static struct my_option my_long_options[] = {"password", 'p', "Password to use when connecting to server. If password is not given it's asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef __WIN__ +#ifdef _WIN32 {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif @@ -222,8 +225,11 @@ file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n"); static my_bool get_one_option(const struct my_option *opt, const char *argument, - const char *filename __attribute__((unused))) + const char *filename) { + /* Track when protocol is set via CLI to not force overrides */ + static my_bool ignore_protocol_override = FALSE; + switch(opt->id) { case 'p': if (argument == disabled_my_option) @@ -246,10 +252,18 @@ get_one_option(const struct my_option *opt, const char *argument, else tty_password= 1; break; -#ifdef __WIN__ +#ifdef _WIN32 case 'W': opt_protocol = MYSQL_PROTOCOL_PIPE; opt_local_file=1; + + /* Prioritize pipe if explicit via command line */ + if (filename[0] == '\0') + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + break; #endif case OPT_MYSQL_PROTOCOL: @@ -259,6 +273,46 @@ get_one_option(const struct my_option *opt, const char *argument, sf_leaking_memory= 1; /* no memory leak reports here */ exit(1); } + + /* Specification of protocol via CLI trumps implicit overrides */ + if (filename[0] == '\0') + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + break; + case 'P': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* If port is set via CLI, try to force protocol to TCP */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = MYSQL_PROTOCOL_TCP; + } + break; + case 'S': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == MYSQL_PROTOCOL_TCP) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* Prioritize socket if set via command line */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + } break; case '#': DBUG_PUSH(argument ? argument : "d:t:o"); @@ -647,6 +701,9 @@ int main(int argc, char **argv) MY_INIT(argv[0]); sf_leaking_memory=1; /* don't report memory leaks on early exits */ + /* We need to know if protocol-related options originate from CLI args */ + my_defaults_mark_files = TRUE; + load_defaults_or_exit("my", load_default_groups, &argc, &argv); /* argv is changed in the program */ argv_to_free= argv; @@ -655,6 +712,14 @@ int main(int argc, char **argv) free_defaults(argv_to_free); return(1); } + + /* Command line options override configured protocol */ + if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT + && protocol_to_force != opt_protocol) + { + warn_protocol_override(current_host, &opt_protocol, protocol_to_force); + } + sf_leaking_memory=0; /* from now on we cleanup properly */ if (opt_use_threads && !lock_tables) diff --git a/client/mysqlshow.c b/client/mysqlshow.c index a89f4eb1dd2..9b31d87225c 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -41,6 +41,8 @@ static char *opt_plugin_dir= 0, *opt_default_auth= 0; static uint opt_protocol=0; +static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; + static void get_options(int *argc,char ***argv); static uint opt_mysql_port=0; static int list_dbs(MYSQL *mysql,const char *wild); @@ -70,11 +72,23 @@ int main(int argc, char **argv) static char **defaults_argv; MY_INIT(argv[0]); sf_leaking_memory=1; /* don't report memory leaks on early exits */ + + /* We need to know if protocol-related options originate from CLI args */ + my_defaults_mark_files = TRUE; + load_defaults_or_exit("my", load_default_groups, &argc, &argv); defaults_argv=argv; get_options(&argc,&argv); + + /* Command line options override configured protocol */ + if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT + && protocol_to_force != opt_protocol) + { + warn_protocol_override(host, &opt_protocol, protocol_to_force); + } + sf_leaking_memory=0; /* from now on we cleanup properly */ wild=0; if (argc) @@ -233,7 +247,7 @@ static struct my_option my_long_options[] = &opt_mysql_port, &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef __WIN__ +#ifdef _WIN32 {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif @@ -290,8 +304,12 @@ are shown."); static my_bool get_one_option(const struct my_option *opt, const char *argument, - const char *filename __attribute__((unused))) + const char *filename) { + + /* Track when protocol is set via CLI to not force overrides */ + static my_bool ignore_protocol_override = FALSE; + switch(opt->id) { case 'v': opt_verbose++; @@ -318,8 +336,15 @@ get_one_option(const struct my_option *opt, const char *argument, tty_password=1; break; case 'W': -#ifdef __WIN__ +#ifdef _WIN32 opt_protocol = MYSQL_PROTOCOL_PIPE; + + /* Prioritize pipe if explicit via command line */ + if (filename[0] == '\0') + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } #endif break; case OPT_MYSQL_PROTOCOL: @@ -329,6 +354,46 @@ get_one_option(const struct my_option *opt, const char *argument, sf_leaking_memory= 1; /* no memory leak reports here */ exit(1); } + + /* Specification of protocol via CLI trumps implicit overrides */ + if (filename[0] == '\0') + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + break; + case 'P': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* If port is set via CLI, try to force protocol to TCP */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = MYSQL_PROTOCOL_TCP; + } + break; + case 'S': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == MYSQL_PROTOCOL_TCP) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* Prioritize socket if set via command line */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + } break; case '#': DBUG_PUSH(argument ? argument : "d:t:o"); diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 08569f2e1a4..5871e899fad 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -86,16 +86,15 @@ TODO: #include <my_dir.h> #include <signal.h> #include <sslopt-vars.h> -#ifndef __WIN__ +#ifndef _WIN32 #include <sys/wait.h> #endif #include <ctype.h> #include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ -#ifdef __WIN__ +#ifdef _WIN32 #define srandom srand -#define random rand -#define snprintf _snprintf +#define random() (long)rand() #endif @@ -173,6 +172,8 @@ File csv_file; static uint opt_protocol= 0; +static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; + static int get_options(int *argc,char ***argv); static uint opt_mysql_port= 0; @@ -280,7 +281,7 @@ static long int timedif(struct timeval a, struct timeval b) return s + us; } -#ifdef __WIN__ +#ifdef _WIN32 static int gettimeofday(struct timeval *tp, void *tzp) { unsigned int ticks; @@ -319,6 +320,9 @@ int main(int argc, char **argv) MY_INIT(argv[0]); sf_leaking_memory=1; /* don't report memory leaks on early exits */ + /* We need to know if protocol-related options originate from CLI args */ + my_defaults_mark_files = TRUE; + load_defaults_or_exit("my", load_default_groups, &argc, &argv); defaults_argv=argv; if (get_options(&argc,&argv)) @@ -327,6 +331,14 @@ int main(int argc, char **argv) my_end(0); exit(1); } + + /* Command line options override configured protocol */ + if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT + && protocol_to_force != opt_protocol) + { + warn_protocol_override(host, &opt_protocol, protocol_to_force); + } + sf_leaking_memory=0; /* from now on we cleanup properly */ /* Seed the random number generator if we will be using it. */ @@ -652,7 +664,7 @@ static struct my_option my_long_options[] = {"password", 'p', "Password to use when connecting to server. If password is not given it's " "asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef __WIN__ +#ifdef _WIN32 {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif @@ -727,8 +739,11 @@ static void usage(void) static my_bool get_one_option(const struct my_option *opt, const char *argument, - const char *filename __attribute__((unused))) + const char *filename) { + /* Track when protocol is set via CLI to not force overrides */ + static my_bool ignore_protocol_override = FALSE; + DBUG_ENTER("get_one_option"); switch(opt->id) { case 'v': @@ -756,8 +771,15 @@ get_one_option(const struct my_option *opt, const char *argument, tty_password= 1; break; case 'W': -#ifdef __WIN__ +#ifdef _WIN32 opt_protocol= MYSQL_PROTOCOL_PIPE; + + /* Prioritize pipe if explicit via command line */ + if (filename[0] == '\0') + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } #endif break; case OPT_MYSQL_PROTOCOL: @@ -767,6 +789,46 @@ get_one_option(const struct my_option *opt, const char *argument, sf_leaking_memory= 1; /* no memory leak reports here */ exit(1); } + + /* Specification of protocol via CLI trumps implicit overrides */ + if (filename[0] == '\0') + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + break; + case 'P': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* If port is set via CLI, try to force protocol to TCP */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = MYSQL_PROTOCOL_TCP; + } + break; + case 'S': + /* If port and socket are set, fall back to default behavior */ + if (protocol_to_force == MYSQL_PROTOCOL_TCP) + { + ignore_protocol_override = TRUE; + protocol_to_force = MYSQL_PROTOCOL_DEFAULT; + } + + /* Prioritize socket if set via command line */ + if (filename[0] == '\0' && + !ignore_protocol_override && + protocol_to_force == MYSQL_PROTOCOL_DEFAULT) + { + protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + } break; case '#': DBUG_PUSH(argument ? argument : default_dbug_option); diff --git a/client/mysqltest.cc b/client/mysqltest.cc index c7ddc0d0d6a..2c609bd9815 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -65,9 +65,8 @@ #define SIGNAL_FMT "signal %d" #endif -#include <my_context.h> static my_bool non_blocking_api_enabled= 0; -#if !defined(EMBEDDED_LIBRARY) && !defined(MY_CONTEXT_DISABLE) +#if !defined(EMBEDDED_LIBRARY) #define WRAP_NONBLOCK_ENABLED non_blocking_api_enabled #include "../tests/nonblock-wrappers.h" #endif @@ -1494,8 +1493,18 @@ void free_used_memory() } +#ifdef EMBEDDED_LIBRARY +void ha_pre_shutdown(); +#endif + + ATTRIBUTE_NORETURN static void cleanup_and_exit(int exit_code) { +#ifdef EMBEDDED_LIBRARY + if (server_initialized) + ha_pre_shutdown(); +#endif + free_used_memory(); /* Only call mysql_server_end if mysql_server_init has been called */ @@ -4965,7 +4974,8 @@ void do_set_charset(struct st_command *command) if(*p) *p++= 0; command->last_argument= p; - charset_info= get_charset_by_csname(charset_name,MY_CS_PRIMARY,MYF(MY_WME)); + charset_info= get_charset_by_csname(charset_name,MY_CS_PRIMARY, + MYF(MY_WME | MY_UTF8_IS_UTF8MB3)); if (!charset_info) abort_not_supported_test("Test requires charset '%s'", charset_name); } @@ -6043,14 +6053,12 @@ void do_connect(struct st_command *command) if (opt_connect_timeout) mysql_options(con_slot->mysql, MYSQL_OPT_CONNECT_TIMEOUT, (void *) &opt_connect_timeout); -#ifndef MY_CONTEXT_DISABLE if (mysql_options(con_slot->mysql, MYSQL_OPT_NONBLOCK, 0)) die("Failed to initialise non-blocking API"); -#endif if (opt_compress || con_compress) mysql_options(con_slot->mysql, MYSQL_OPT_COMPRESS, NullS); mysql_options(con_slot->mysql, MYSQL_SET_CHARSET_NAME, - csname?csname: charset_info->csname); + csname ? csname : charset_info->cs_name.str); if (opt_charsets_dir) mysql_options(con_slot->mysql, MYSQL_SET_CHARSET_DIR, opt_charsets_dir); @@ -8172,9 +8180,10 @@ void handle_error(struct st_command *command, const char *err_sqlstate, DYNAMIC_STRING *ds) { int i; - DBUG_ENTER("handle_error"); + var_set_int("$errno", err_errno); + command->used_replace= 1; if (command->require_file) { @@ -8185,7 +8194,8 @@ void handle_error(struct st_command *command, */ if (err_errno == CR_SERVER_LOST || err_errno == CR_SERVER_GONE_ERROR) - die("require query '%s' failed: %d: %s", command->query, + die("require query '%s' failed: %s (%d): %s", command->query, + get_errname_from_code(err_errno), err_errno, err_error); /* Abort the run of this test, pass the failed query as reason */ @@ -8195,7 +8205,9 @@ void handle_error(struct st_command *command, if (command->abort_on_error) { - report_or_die("query '%s' failed: %d: %s", command->query, err_errno, + report_or_die("query '%s' failed: %s (%d): %s", command->query, + get_errname_from_code(err_errno), + err_errno, err_error); DBUG_VOID_RETURN; } @@ -8244,9 +8256,12 @@ void handle_error(struct st_command *command, if (command->expected_errors.count > 0) { if (command->expected_errors.err[0].type == ERR_ERRNO) - report_or_die("query '%s' failed with wrong errno %d: '%s', instead of " - "%d...", - command->query, err_errno, err_error, + report_or_die("query '%s' failed with wrong errno %s (%d): '%s', " + "instead of %s (%d)...", + command->query, + get_errname_from_code(err_errno), + err_errno, err_error, + get_errname_from_code(command->expected_errors.err[0].code.errnum), command->expected_errors.err[0].code.errnum); else report_or_die("query '%s' failed with wrong sqlstate %s: '%s', " @@ -8279,8 +8294,11 @@ void handle_no_error(struct st_command *command) command->expected_errors.err[0].code.errnum != 0) { /* Error code we wanted was != 0, i.e. not an expected success */ - report_or_die("query '%s' succeeded - should have failed with errno %d...", - command->query, command->expected_errors.err[0].code.errnum); + report_or_die("query '%s' succeeded - should have failed with error " + "%s (%d)...", + command->query, + get_errname_from_code(command->expected_errors.err[0].code.errnum), + command->expected_errors.err[0].code.errnum); } else if (command->expected_errors.err[0].type == ERR_SQLSTATE && strcmp(command->expected_errors.err[0].code.sqlstate,"00000") != 0) @@ -8359,7 +8377,7 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, Get the warnings from mysql_stmt_prepare and keep them in a separate string */ - if (!disable_warnings) + if (!disable_warnings && prepare_warnings_enabled) append_warnings(&ds_prepare_warnings, mysql); /* @@ -8390,117 +8408,125 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, goto end; } - /* - When running in cursor_protocol get the warnings from execute here - and keep them in a separate string for later. - */ - if (cursor_protocol_enabled && !disable_warnings) - append_warnings(&ds_execute_warnings, mysql); - - /* - We instruct that we want to update the "max_length" field in - mysql_stmt_store_result(), this is our only way to know how much - buffer to allocate for result data - */ + int err; + do { - my_bool one= 1; - if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one)) - die("mysql_stmt_attr_set(STMT_ATTR_UPDATE_MAX_LENGTH) failed': %d %s", - mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); - } + /* + When running in cursor_protocol get the warnings from execute here + and keep them in a separate string for later. + */ + if (cursor_protocol_enabled && !disable_warnings) + append_warnings(&ds_execute_warnings, mysql); - /* - If we got here the statement succeeded and was expected to do so, - get data. Note that this can still give errors found during execution! - Store the result of the query if if will return any fields - */ - if (mysql_stmt_field_count(stmt) && mysql_stmt_store_result(stmt)) - { - handle_error(command, mysql_stmt_errno(stmt), - mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); - goto end; - } + /* + We instruct that we want to update the "max_length" field in + mysql_stmt_store_result(), this is our only way to know how much + buffer to allocate for result data + */ + { + my_bool one= 1; + if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one)) + die("mysql_stmt_attr_set(STMT_ATTR_UPDATE_MAX_LENGTH) failed': %d %s", + mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); + } - /* If we got here the statement was both executed and read successfully */ - handle_no_error(command); - if (!disable_result_log) - { /* - Not all statements creates a result set. If there is one we can - now create another normal result set that contains the meta - data. This set can be handled almost like any other non prepared - statement result set. + If we got here the statement succeeded and was expected to do so, + get data. Note that this can still give errors found during execution! + Store the result of the query if if will return any fields */ - if ((res= mysql_stmt_result_metadata(stmt)) != NULL) + if (mysql_stmt_field_count(stmt) && mysql_stmt_store_result(stmt)) { - /* Take the column count from meta info */ - MYSQL_FIELD *fields= mysql_fetch_fields(res); - uint num_fields= mysql_num_fields(res); + handle_error(command, mysql_stmt_errno(stmt), + mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); + goto end; + } - if (display_metadata) - append_metadata(ds, fields, num_fields); + if (!disable_result_log) + { + /* + Not all statements creates a result set. If there is one we can + now create another normal result set that contains the meta + data. This set can be handled almost like any other non prepared + statement result set. + */ + if ((res= mysql_stmt_result_metadata(stmt)) != NULL) + { + /* Take the column count from meta info */ + MYSQL_FIELD *fields= mysql_fetch_fields(res); + uint num_fields= mysql_num_fields(res); - if (!display_result_vertically) - append_table_headings(ds, fields, num_fields); + if (display_metadata) + append_metadata(ds, fields, num_fields); - append_stmt_result(ds, stmt, fields, num_fields); + if (!display_result_vertically) + append_table_headings(ds, fields, num_fields); - mysql_free_result(res); /* Free normal result set with meta data */ + append_stmt_result(ds, stmt, fields, num_fields); - /* - Normally, if there is a result set, we do not show warnings from the - prepare phase. This is because some warnings are generated both during - prepare and execute; this would generate different warning output - between normal and ps-protocol test runs. + mysql_free_result(res); /* Free normal result set with meta data */ - The --enable_prepare_warnings command can be used to change this so - that warnings from both the prepare and execute phase are shown. - */ - if (!disable_warnings && !prepare_warnings_enabled) - dynstr_set(&ds_prepare_warnings, NULL); - } - else - { - /* - This is a query without resultset - */ - } + /* + Normally, if there is a result set, we do not show warnings from the + prepare phase. This is because some warnings are generated both during + prepare and execute; this would generate different warning output + between normal and ps-protocol test runs. - /* - Fetch info before fetching warnings, since it will be reset - otherwise. - */ - if (!disable_info) - append_info(ds, mysql_stmt_affected_rows(stmt), mysql_info(mysql)); + The --enable_prepare_warnings command can be used to change this so + that warnings from both the prepare and execute phase are shown. + */ + if (!disable_warnings && !prepare_warnings_enabled) + dynstr_set(&ds_prepare_warnings, NULL); + } + else + { + /* + This is a query without resultset + */ + } - if (display_session_track_info) - append_session_track_info(ds, mysql); + /* + Fetch info before fetching warnings, since it will be reset + otherwise. + */ + 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 */ - /* Append warnings to ds - if there are any */ - if (append_warnings(&ds_execute_warnings, mysql) || - ds_execute_warnings.length || - ds_prepare_warnings.length || - ds_warnings->length) + if (!disable_warnings && !mysql_more_results(stmt->mysql)) { - dynstr_append_mem(ds, "Warnings:\n", 10); - if (ds_warnings->length) - dynstr_append_mem(ds, ds_warnings->str, - ds_warnings->length); - if (ds_prepare_warnings.length) - dynstr_append_mem(ds, ds_prepare_warnings.str, - ds_prepare_warnings.length); - if (ds_execute_warnings.length) - dynstr_append_mem(ds, ds_execute_warnings.str, - ds_execute_warnings.length); + /* Get the warnings from execute */ + + /* Append warnings to ds - if there are any */ + if (append_warnings(&ds_execute_warnings, mysql) || + ds_execute_warnings.length || + ds_prepare_warnings.length || + ds_warnings->length) + { + dynstr_append_mem(ds, "Warnings:\n", 10); + if (ds_warnings->length) + dynstr_append_mem(ds, ds_warnings->str, + ds_warnings->length); + if (ds_prepare_warnings.length) + dynstr_append_mem(ds, ds_prepare_warnings.str, + ds_prepare_warnings.length); + if (ds_execute_warnings.length) + dynstr_append_mem(ds, ds_execute_warnings.str, + ds_execute_warnings.length); + } } } - } + } while ( !(err= mysql_stmt_next_result(stmt))); + if (err > 0) + /* We got an error from mysql_next_result, maybe expected */ + handle_error(command, mysql_errno(mysql), mysql_error(mysql), + mysql_sqlstate(mysql), ds); + else + handle_no_error(command); end: if (!disable_warnings) { @@ -9203,7 +9229,13 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) */ if (ps_protocol_enabled && complete_query && - match_re(&ps_re, query)) + /* + Check that a statement is not one of PREPARE FROM, EXECUTE, + DEALLOCATE PREPARE (possibly prefixed with the 'SET STATEMENT ... FOR' + clause. These statement shouldn't be run using prepared statement C API. + All other statements can be run using prepared statement C API. + */ + !match_re(&ps_re, query)) run_query_stmt(cn, command, query, query_len, ds, &ds_warnings); else run_query_normal(cn, command, flags, query, query_len, @@ -9277,10 +9309,30 @@ void init_re_comp(regex_t *re, const char* str) void init_re(void) { /* + * Prior to the task MDEV-16708 a value of the string ps_re_str contained + * a regular expression to match statements that SHOULD BE run in PS mode. + * The task MDEV-16708 modifies interpretation of this regular expression + * and now it is used for matching statements that SHOULDN'T be run in + * PS mode. These statement are PREPARE FROM, EXECUTE, DEALLOCATE PREPARE + * possibly prefixed with the clause SET STATEMENT ... FOR + */ + const char *ps_re_str = + "^(" + "[[:space:]]*PREPARE[[:space:]]|" + "[[:space:]]*EXECUTE[[:space:]]|" + "[[:space:]]*DEALLOCATE[[:space:]]+PREPARE[[:space:]]|" + "[[:space:]]*DROP[[:space:]]+PREPARE[[:space:]]|" + "(SET[[:space:]]+STATEMENT[[:space:]]+.+[[:space:]]+FOR[[:space:]]+)?" + "EXECUTE[[:space:]]+|" + "(SET[[:space:]]+STATEMENT[[:space:]]+.+[[:space:]]+FOR[[:space:]]+)?" + "PREPARE[[:space:]]+" + ")"; + + /* Filter for queries that can be run using the - MySQL Prepared Statements C API + Stored procedures */ - const char *ps_re_str = + const char *sp_re_str = "^(" "[[:space:]]*ALTER[[:space:]]+SEQUENCE[[:space:]]|" "[[:space:]]*ALTER[[:space:]]+TABLE[[:space:]]|" @@ -9334,12 +9386,6 @@ void init_re(void) ")"; /* - Filter for queries that can be run using the - Stored procedures - */ - const char *sp_re_str =ps_re_str; - - /* Filter for queries that can be run as views */ const char *view_re_str = @@ -9749,7 +9795,7 @@ int main(int argc, char **argv) if (opt_compress) mysql_options(con->mysql,MYSQL_OPT_COMPRESS,NullS); mysql_options(con->mysql, MYSQL_SET_CHARSET_NAME, - charset_info->csname); + charset_info->cs_name.str); if (opt_charsets_dir) mysql_options(con->mysql, MYSQL_SET_CHARSET_DIR, opt_charsets_dir); @@ -10207,10 +10253,28 @@ int main(int argc, char **argv) report_or_die("Parsing is already enabled"); break; case Q_DIE: + { + char message[160]; + const char *msg; + DYNAMIC_STRING ds_echo; + + if (command->first_argument[0]) + { + /* Evaluate variables in the message */ + init_dynamic_string(&ds_echo, "", command->query_len, 256); + do_eval(&ds_echo, command->first_argument, command->end, FALSE); + strmake(message, ds_echo.str, MY_MIN(sizeof(message)-1, + ds_echo.length)); + dynstr_free(&ds_echo); + msg= message; + } + else + msg= "Explicit --die command executed"; + /* Abort test with error code and error message */ - die("%s", command->first_argument[0] ? command->first_argument : - "Explicit --die command executed"); + die("%s", msg); break; + } case Q_EXIT: /* Stop processing any more commands */ abort_flag= 1; diff --git a/client/readline.cc b/client/readline.cc index 8d3d97b8585..6b9e8239984 100644 --- a/client/readline.cc +++ b/client/readline.cc @@ -34,7 +34,7 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file) { LINE_BUFFER *line_buff; -#ifndef __WIN__ +#ifndef _WIN32 MY_STAT input_file_stat; if (my_fstat(fileno(file), &input_file_stat, MYF(MY_WME)) || MY_S_ISDIR(input_file_stat.st_mode) || |