summaryrefslogtreecommitdiff
path: root/client/mysql.cc
diff options
context:
space:
mode:
Diffstat (limited to 'client/mysql.cc')
-rw-r--r--client/mysql.cc130
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*) &current_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);