diff options
Diffstat (limited to 'client/mysql.cc')
-rw-r--r-- | client/mysql.cc | 130 |
1 files changed, 96 insertions, 34 deletions
diff --git a/client/mysql.cc b/client/mysql.cc index 16923eaf149..b79dda51317 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -44,7 +44,7 @@ #include <locale.h> #endif -const char *VER= "14.3"; +const char *VER= "14.5"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 @@ -134,7 +134,8 @@ static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, vertical=0, line_numbers=1, column_names=1,opt_html=0, opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0, tty_password= 0, opt_nobeep=0, opt_reconnect=1, - default_charset_used= 0, opt_secure_auth= 0; + default_charset_used= 0, opt_secure_auth= 0, + default_pager_set= 0; static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0; static my_string opt_mysql_unix_port=0; static int connect_flag=CLIENT_INTERACTIVE; @@ -173,9 +174,7 @@ static CHARSET_INFO *charset_info= &my_charset_latin1; #include "sslopt-vars.h" -#ifndef DBUG_OFF const char *default_dbug_option="d:t:o,/tmp/mysql.trace"; -#endif void tee_fprintf(FILE *file, const char *fmt, ...); void tee_fputs(const char *s, FILE *file); @@ -227,11 +226,12 @@ typedef struct { } COMMANDS; static COMMANDS commands[] = { - { "help", 'h', com_help, 1, "Display this help." }, { "?", '?', com_help, 1, "Synonym for `help'." }, { "clear", 'c', com_clear, 0, "Clear command."}, { "connect",'r', com_connect,1, "Reconnect to the server. Optional arguments are db and host." }, + { "delimiter", 'd', com_delimiter, 1, + "Set query delimiter. " }, #ifdef USE_POPEN { "edit", 'e', com_edit, 0, "Edit command with $EDITOR."}, #endif @@ -239,6 +239,7 @@ static COMMANDS commands[] = { "Send command to mysql server, display result vertically."}, { "exit", 'q', com_quit, 0, "Exit mysql. Same as quit."}, { "go", 'g', com_go, 0, "Send command to mysql server." }, + { "help", 'h', com_help, 1, "Display this help." }, #ifdef USE_POPEN { "nopager",'n', com_nopager,0, "Disable pager, print to stdout." }, #endif @@ -261,8 +262,6 @@ static COMMANDS commands[] = { "Set outfile [to_outfile]. Append everything into given outfile." }, { "use", 'u', com_use, 1, "Use another database. Takes database name as argument." }, - { "delimiter", 'd', com_delimiter, 1, - "Set query delimiter. " }, /* Get bash-like expansion for some commands */ { "create table", 0, 0, 0, ""}, { "create database", 0, 0, 0, ""}, @@ -331,8 +330,11 @@ int main(int argc,char *argv[]) strmov(pager, "stdout"); // the default, if --pager wasn't given { char *tmp=getenv("PAGER"); - if (tmp) - strmov(default_pager,tmp); + if (tmp && strlen(tmp)) + { + default_pager_set= 1; + strmov(default_pager, tmp); + } } if (!isatty(0) || !isatty(1)) { @@ -467,6 +469,8 @@ static struct my_option my_long_options[] = { {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"help", 'I', "Synonym for -?", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, + 0, 0, 0, 0, 0}, {"auto-rehash", OPT_AUTO_REHASH, "Enable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time. Disable with --disable-auto-rehash.", (gptr*) &rehash, (gptr*) &rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -484,8 +488,11 @@ static struct my_option my_long_options[] = {"compress", 'C', "Use compression in server/client protocol.", (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, -#ifndef DBUG_OFF - {"debug", '#', "Output debug log.", (gptr*) &default_dbug_option, +#ifdef DBUG_OFF + {"debug", '#', "This is a non-debug version. Catch this and exit", + 0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0}, +#else + {"debug", '#', "Output debug log", (gptr*) &default_dbug_option, (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif {"database", 'D', "Database to use.", (gptr*) ¤t_db, @@ -608,19 +615,27 @@ static struct my_option my_long_options[] = GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"connect_timeout", OPT_CONNECT_TIMEOUT, "", (gptr*) &opt_connect_timeout, + {"connect_timeout", OPT_CONNECT_TIMEOUT, + "Number of seconds before connection timeout.", + (gptr*) &opt_connect_timeout, (gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0, 0, 1}, - {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "", + {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, + "Max packet length to send to, or receive from server", (gptr*) &max_allowed_packet, (gptr*) &max_allowed_packet, 0, GET_ULONG, REQUIRED_ARG, 16 *1024L*1024L, 4096, (longlong) 2*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0}, - {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "", + {"net_buffer_length", OPT_NET_BUFFER_LENGTH, + "Buffer for TCP/IP and socket communication", (gptr*) &net_buffer_length, (gptr*) &net_buffer_length, 0, GET_ULONG, REQUIRED_ARG, 16384, 1024, 512*1024*1024L, MALLOC_OVERHEAD, 1024, 0}, - {"select_limit", OPT_SELECT_LIMIT, "", (gptr*) &select_limit, + {"select_limit", OPT_SELECT_LIMIT, + "Automatic limit for SELECT when using --safe-updates", + (gptr*) &select_limit, (gptr*) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ~0L, 0, 1, 0}, - {"max_join_size", OPT_MAX_JOIN_SIZE, "", (gptr*) &max_join_size, + {"max_join_size", OPT_MAX_JOIN_SIZE, + "Automatic limit for rows in a join when using --safe-updates", + (gptr*) &max_join_size, (gptr*) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ~0L, 0, 1, 0}, {"secure-auth", OPT_SECURE_AUTH, "Refuse client connecting to server if it" @@ -689,11 +704,16 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), else { opt_nopager= 0; - if (argument) + if (argument && strlen(argument)) + { + default_pager_set= 1; strmov(pager, argument); - else + strmov(default_pager, pager); + } + else if (default_pager_set) strmov(pager, default_pager); - strmov(default_pager, pager); + else + opt_nopager= 1; } break; case OPT_NOPAGER: @@ -814,11 +834,14 @@ static int get_options(int argc, char **argv) strmov(default_pager, "stdout"); strmov(pager, "stdout"); opt_nopager= 1; + default_pager_set= 0; opt_outfile= 0; opt_reconnect= 0; connect_flag= 0; /* Not in interactive mode */ } - if (!(charset_info= get_charset_by_csname(default_charset, + + if (strcmp(default_charset, charset_info->csname) && + !(charset_info= get_charset_by_csname(default_charset, MY_CS_PRIMARY, MYF(MY_WME)))) exit(1); if (argc > 1) @@ -1535,7 +1558,7 @@ static int com_server_help(String *buffer __attribute__((unused)), init_pager(); char last_char; - int num_name, num_cat; + int num_name= 0, num_cat= 0; LINT_INIT(num_name); LINT_INIT(num_cat); @@ -1577,8 +1600,8 @@ static int com_help(String *buffer __attribute__((unused)), char *line __attribute__((unused))) { - reg1 int i; - char * help_arg= strchr(line,' '); + reg1 int i, j; + char * help_arg= strchr(line,' '), buff[32], *end; if (help_arg) return com_server_help(buffer,line,help_arg+1); @@ -1591,8 +1614,11 @@ com_help(String *buffer __attribute__((unused)), put_info("Note that all text commands must be first on line and end with ';'",INFO_INFO); for (i = 0; commands[i].name; i++) { + end= strmov(buff, commands[i].name); + for (j= strlen(commands[i].name); j < 10; j++) + end= strmov(end, " "); if (commands[i].func) - tee_fprintf(stdout, "%s\t(\\%c)\t%s\n", commands[i].name, + tee_fprintf(stdout, "%s(\\%c) %s\n", buff, commands[i].cmd_char, commands[i].doc); } if (connected && mysql_get_server_version(&mysql) >= 40100) @@ -2160,12 +2186,17 @@ com_pager(String *buffer, char *line __attribute__((unused))) if (status.batch) return 0; - /* Skip space from file name */ - while (my_isspace(charset_info,*line)) + /* Skip spaces in front of the pager command */ + while (my_isspace(charset_info, *line)) line++; - if (!(param= strchr(line, ' '))) // if pager was not given, use the default + /* Skip the pager command */ + param= strchr(line, ' '); + /* Skip the spaces between the command and the argument */ + while (param && my_isspace(charset_info, *param)) + param++; + if (!param || !strlen(param)) // if pager was not given, use the default { - if (!default_pager[0]) + if (!default_pager_set) { tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n"); opt_nopager=1; @@ -2177,9 +2208,7 @@ com_pager(String *buffer, char *line __attribute__((unused))) } else { - while (my_isspace(charset_info,*param)) - param++; - end=strmake(pager_name, param, sizeof(pager_name)-1); + end= strmake(pager_name, param, sizeof(pager_name)-1); while (end > pager_name && (my_isspace(charset_info,end[-1]) || my_iscntrl(charset_info,end[-1]))) end--; @@ -2188,7 +2217,7 @@ com_pager(String *buffer, char *line __attribute__((unused))) strmov(default_pager, pager_name); } opt_nopager=0; - tee_fprintf(stdout, "PAGER set to %s\n", pager); + tee_fprintf(stdout, "PAGER set to '%s'\n", pager); return 0; } @@ -2199,6 +2228,7 @@ com_nopager(String *buffer __attribute__((unused)), { strmov(pager, "stdout"); opt_nopager=1; + PAGER= stdout; tee_fprintf(stdout, "PAGER set to stdout\n"); return 0; } @@ -2433,8 +2463,9 @@ com_delimiter(String *buffer __attribute__((unused)), char *line) static int com_use(String *buffer __attribute__((unused)), char *line) { - char *tmp; - char buff[256]; + char *tmp, buff[FN_REFLEN + 1]; + MYSQL_RES *res; + MYSQL_ROW row; bzero(buff, sizeof(buff)); strmov(buff, line); @@ -2444,6 +2475,31 @@ com_use(String *buffer __attribute__((unused)), char *line) put_info("USE must be followed by a database name", INFO_ERROR); return 0; } + + /* + We need to recheck the current database, because it may change + under our feet, for example if DROP DATABASE or RENAME DATABASE + (latter one not yet available by the time the comment was written) + */ + current_db= 0; // Let's reset current_db, assume it's gone + /* + We don't care about in case of an error below because current_db + was just set to 0. + */ + if (!mysql_query(&mysql, "SELECT DATABASE()") && + (res= mysql_use_result(&mysql))) + { + row= mysql_fetch_row(res); + if (row[0] && + (!current_db || cmp_database(charset_info, current_db, row[0]))) + { + my_free(current_db, MYF(MY_ALLOW_ZERO_PTR)); + current_db= my_strdup(row[0], MYF(MY_WME)); + } + (void) mysql_fetch_row(res); // Read eof + mysql_free_result(res); + } + if (!current_db || cmp_database(charset_info, current_db, tmp)) { if (one_database) @@ -2649,6 +2705,9 @@ com_status(String *buffer __attribute__((unused)), char *line __attribute__((unused))) { const char *status; + char buff[22]; + ulonglong id; + tee_puts("--------------", stdout); usage(1); /* Print version */ if (connected) @@ -2694,6 +2753,9 @@ com_status(String *buffer __attribute__((unused)), tee_fprintf(stdout, "Server version:\t\t%s\n", mysql_get_server_info(&mysql)); tee_fprintf(stdout, "Protocol version:\t%d\n", mysql_get_proto_info(&mysql)); tee_fprintf(stdout, "Connection:\t\t%s\n", mysql_get_host_info(&mysql)); + if ((id= mysql_insert_id(&mysql))) + tee_fprintf(stdout, "Insert id:\t\t%s\n", llstr(id, buff)); + tee_fprintf(stdout, "Client characterset:\t%s\n", charset_info->name); tee_fprintf(stdout, "Server characterset:\t%s\n", mysql.charset->name); |