summaryrefslogtreecommitdiff
path: root/client/mysql.cc
diff options
context:
space:
mode:
Diffstat (limited to 'client/mysql.cc')
-rw-r--r--client/mysql.cc210
1 files changed, 127 insertions, 83 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index edcc72b60bf..e605d517d2c 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -59,11 +59,6 @@ static char *server_version= NULL;
/* Array of options to pass to libemysqld */
#define MAX_SERVER_ARGS 64
-/* Version numbers for deprecation messages */
-#define VER_CELOSIA "5.6"
-
-void* sql_alloc(unsigned size); // Don't use mysqld alloc for these
-void sql_element_free(void *ptr);
#include "sql_string.h"
extern "C" {
@@ -107,7 +102,7 @@ extern "C" {
#define vidattr(A) {} // Can't get this to work
#endif
-#ifdef FN_NO_CASE_SENCE
+#ifdef FN_NO_CASE_SENSE
#define cmp_database(cs,A,B) my_strcasecmp((cs), (A), (B))
#else
#define cmp_database(cs,A,B) strcmp((A),(B))
@@ -148,8 +143,9 @@ static my_bool 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,
+ opt_secure_auth= 0,
default_pager_set= 0, opt_sigint_ignore= 0,
+ auto_vertical_output= 0,
show_warnings= 0, executing_query= 0, interrupted_query= 0,
ignore_spaces= 0;
static my_bool debug_info_flag, debug_check_flag;
@@ -162,7 +158,8 @@ static char * opt_mysql_unix_port=0;
static int connect_flag=CLIENT_INTERACTIVE;
static char *current_host,*current_db,*current_user=0,*opt_password=0,
*current_prompt=0, *delimiter_str= 0,
- *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
+ *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME,
+ *opt_init_command= 0;
static char *histfile;
static char *histfile_tmp;
static String glob_buffer,old_buffer;
@@ -191,6 +188,7 @@ static MEM_ROOT hash_mem_root;
static uint prompt_counter;
static char delimiter[16]= DEFAULT_DELIMITER;
static uint delimiter_length= 1;
+unsigned short terminal_width= 80;
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
@@ -244,6 +242,8 @@ static const char* construct_prompt();
static char *get_arg(char *line, my_bool get_next_arg);
static void init_username();
static void add_int_to_prompt(int toadd);
+static int get_result_width(MYSQL_RES *res);
+static int get_field_disp_length(MYSQL_FIELD * field);
/* A structure which contains information on the commands this program
can understand. */
@@ -459,7 +459,6 @@ static COMMANDS commands[] = {
{ "FORCE", 0, 0, 0, ""},
{ "FOREIGN", 0, 0, 0, ""},
{ "FOUND", 0, 0, 0, ""},
- { "FRAC_SECOND", 0, 0, 0, ""},
{ "FROM", 0, 0, 0, ""},
{ "FULL", 0, 0, 0, ""},
{ "FULLTEXT", 0, 0, 0, ""},
@@ -704,7 +703,6 @@ static COMMANDS commands[] = {
{ "SQL_NO_CACHE", 0, 0, 0, ""},
{ "SQL_SMALL_RESULT", 0, 0, 0, ""},
{ "SQL_THREAD", 0, 0, 0, ""},
- { "SQL_TSI_FRAC_SECOND", 0, 0, 0, ""},
{ "SQL_TSI_SECOND", 0, 0, 0, ""},
{ "SQL_TSI_MINUTE", 0, 0, 0, ""},
{ "SQL_TSI_HOUR", 0, 0, 0, ""},
@@ -1071,6 +1069,10 @@ static void mysql_end_timer(ulong start_time,char *buff);
static void nice_time(double sec,char *buff,bool part_second);
extern "C" sig_handler mysql_end(int sig);
extern "C" sig_handler handle_sigint(int sig);
+#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
+static sig_handler window_resize(int sig);
+#endif
+
int main(int argc,char *argv[])
{
@@ -1120,7 +1122,11 @@ int main(int argc,char *argv[])
close(stdout_fileno_copy); /* Clean up dup(). */
}
- load_defaults("my",load_default_groups,&argc,&argv);
+ if (load_defaults("my",load_default_groups,&argc,&argv))
+ {
+ my_end(0);
+ exit(1);
+ }
defaults_argv=argv;
if (get_options(argc, (char **) argv))
{
@@ -1150,8 +1156,8 @@ int main(int argc,char *argv[])
if (sql_connect(current_host,current_db,current_user,opt_password,
opt_silent))
{
- quick=1; // Avoid history
- status.exit_status=1;
+ quick= 1; // Avoid history
+ status.exit_status= 1;
mysql_end(-1);
}
if (!status.batch)
@@ -1163,6 +1169,13 @@ int main(int argc,char *argv[])
signal(SIGINT, handle_sigint); // Catch SIGINT to clean up
signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up
+#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
+ /* Readline will call this if it installs a handler */
+ signal(SIGWINCH, window_resize);
+ /* call the SIGWINCH handler to get the default term width */
+ window_resize(0);
+#endif
+
put_info("Welcome to the MySQL monitor. Commands end with ; or \\g.",
INFO_INFO);
sprintf((char*) glob_buffer.ptr(),
@@ -1335,6 +1348,16 @@ err:
}
+#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
+sig_handler window_resize(int sig)
+{
+ struct winsize window_size;
+
+ if (ioctl(fileno(stdin), TIOCGWINSZ, &window_size) == 0)
+ terminal_width= window_size.ws_col;
+}
+#endif
+
static struct my_option my_long_options[] =
{
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
@@ -1356,6 +1379,11 @@ static struct my_option my_long_options[] =
"completion. This gives a quicker start of mysql and disables rehashing "
"on reconnect.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"auto-vertical-output", OPT_AUTO_VERTICAL_OUTPUT,
+ "Automatically switch to vertical output mode if the result is wider "
+ "than the terminal width.",
+ &auto_vertical_output, &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
{"batch", 'B',
"Don't use history file. Disable interactive behavior. (Enables --silent.)",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -1407,21 +1435,18 @@ static struct my_option my_long_options[] =
"is disabled by default.",
&named_cmds, &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
- {"no-named-commands", 'g',
- "Named commands are disabled. Use \\* form only, or use named commands "
- "only in the beginning of a line ending with a semicolon (;). Since "
- "version 10.9, the client now starts with this option ENABLED by default. "
- "Disable with '-G'. Long format commands still work from the first line. "
- "WARNING: option deprecated; use --disable-named-commands instead.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"ignore-spaces", 'i', "Ignore space after function names.",
&ignore_spaces, &ignore_spaces, 0, GET_BOOL, NO_ARG, 0, 0,
0, 0, 0, 0},
+ {"init-command", OPT_INIT_COMMAND,
+ "SQL Command to execute when connecting to MySQL server. Will "
+ "automatically be re-executed when reconnecting.",
+ &opt_init_command, &opt_init_command, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.",
- &opt_local_infile,
- &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ &opt_local_infile, &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"no-beep", 'b', "Turn off beep on error.", &opt_nobeep,
- &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"host", 'h', "Connect to host.", &current_host,
&current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"html", 'H', "Produce HTML output.", &opt_html, &opt_html,
@@ -1430,7 +1455,7 @@ static struct my_option my_long_options[] =
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"line-numbers", OPT_LINE_NUMBERS, "Write line numbers for errors.",
&line_numbers, &line_numbers, 0, GET_BOOL,
- NO_ARG, 1, 0, 0, 0, 0, 0},
+ NO_ARG, 1, 0, 0, 0, 0, 0},
{"skip-line-numbers", 'L', "Don't write line number for errors.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"unbuffered", 'n', "Flush buffer after each query.", &unbuffered,
@@ -1441,10 +1466,6 @@ static struct my_option my_long_options[] =
{"skip-column-names", 'N',
"Don't write column names in results.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"set-variable", 'O',
- "Change the value of a variable. Please note that this option is "
- "deprecated; you can set variables directly with --variable-name=value.",
- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"sigint-ignore", OPT_SIGINT_IGNORE, "Ignore SIGINT (CTRL-C).",
&opt_sigint_ignore, &opt_sigint_ignore, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -1460,10 +1481,6 @@ static struct my_option my_long_options[] =
"This option does not work in batch mode. Disable with --disable-pager. "
"This option is disabled by default.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
- {"no-pager", OPT_NOPAGER,
- "Disable pager and print to stdout. See interactive help (\\h) also. "
- "WARNING: option deprecated; use --disable-pager instead.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"password", 'p',
"Password to use when connecting to server. If password is not given it's asked from the tty.",
@@ -1513,9 +1530,6 @@ static struct my_option my_long_options[] =
"Does not work in batch mode. Disable with --disable-tee. "
"This option is disabled by default.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"no-tee", OPT_NOTEE, "Disable outfile. See interactive help (\\h) also. "
- "WARNING: Option deprecated; use --disable-tee instead.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DONT_ALLOW_USER_CHANGE
{"user", 'u', "User for login if not current user.", &current_user,
&current_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -1615,9 +1629,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir) - 1);
charsets_dir = mysql_charsets_dir;
break;
- case OPT_DEFAULT_CHARSET:
- default_charset_used= 1;
- break;
case OPT_DELIMITER:
if (argument == disabled_my_option)
{
@@ -1651,11 +1662,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
else
init_tee(argument);
break;
- case OPT_NOTEE:
- WARN_DEPRECATED(VER_CELOSIA, "--no-tee", "--disable-tee");
- if (opt_outfile)
- end_tee();
- break;
case OPT_PAGER:
if (argument == disabled_my_option)
opt_nopager= 1;
@@ -1674,10 +1680,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
opt_nopager= 1;
}
break;
- case OPT_NOPAGER:
- WARN_DEPRECATED(VER_CELOSIA, "--no-pager", "--disable-pager");
- opt_nopager= 1;
- break;
case OPT_MYSQL_PROTOCOL:
#ifndef EMBEDDED_LIBRARY
opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
@@ -1721,18 +1723,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
if (!(status.line_buff= batch_readline_command(status.line_buff, argument)))
return 1;
break;
- case 'g':
- WARN_DEPRECATED(VER_CELOSIA, "-g, --no-named-commands", "--skip-named-commands");
- break;
case 'o':
if (argument == disabled_my_option)
one_database= 0;
else
one_database= skip_updates= 1;
break;
- case 'O':
- WARN_DEPRECATED(VER_CELOSIA, "-O, --set-variable", "--variable-name=value");
- break;
case 'p':
if (argument == disabled_my_option)
argument= (char*) ""; // Don't require password
@@ -1828,10 +1824,6 @@ static int get_options(int argc, char **argv)
connect_flag= 0; /* Not in interactive mode */
}
- 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)
{
usage(0);
@@ -2339,8 +2331,10 @@ static bool add_line(String &buffer,char *line,char *in_string,
#ifdef HAVE_READLINE
+C_MODE_START
static char *new_command_generator(const char *text, int);
-extern "C" char **new_mysql_completion (const char *text, int start, int end);
+static char **new_mysql_completion(const char *text, int start, int end);
+C_MODE_END
/*
Tell the GNU Readline library how to complete. We want to try to complete
@@ -2472,9 +2466,9 @@ static void initialize_readline (char *name)
array of matches, or NULL if there aren't any.
*/
-char **new_mysql_completion (const char *text,
- int start __attribute__((unused)),
- int end __attribute__((unused)))
+static char **new_mysql_completion(const char *text,
+ int start __attribute__((unused)),
+ int end __attribute__((unused)))
{
if (!status.batch && !quick)
#if defined(USE_NEW_READLINE_INTERFACE)
@@ -2959,7 +2953,6 @@ com_charset(String *buffer __attribute__((unused)), char *line)
charset_info= new_cs;
mysql_set_character_set(&mysql, charset_info->csname);
default_charset= (char *)charset_info->csname;
- default_charset_used= 1;
put_info("Charset changed", INFO_INFO);
}
else put_info("Charset is not found", INFO_INFO);
@@ -3086,7 +3079,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
print_table_data_html(result);
else if (opt_xml)
print_table_data_xml(result);
- else if (vertical)
+ else if (vertical || (auto_vertical_output && (terminal_width < get_result_width(result))))
print_table_data_vertically(result);
else if (opt_silent && verbose <= 2 && !output_tables)
print_tab_data(result);
@@ -3417,6 +3410,65 @@ print_table_data(MYSQL_RES *result)
my_afree((uchar*) num_flag);
}
+/**
+ Return the length of a field after it would be rendered into text.
+
+ This doesn't know or care about multibyte characters. Assume we're
+ using such a charset. We can't know that all of the upcoming rows
+ for this column will have bytes that each render into some fraction
+ of a character. It's at least possible that a row has bytes that
+ all render into one character each, and so the maximum length is
+ still the number of bytes. (Assumption 1: This can't be better
+ because we can never know the number of characters that the DB is
+ going to send -- only the number of bytes. 2: Chars <= Bytes.)
+
+ @param field Pointer to a field to be inspected
+
+ @returns number of character positions to be used, at most
+*/
+static int get_field_disp_length(MYSQL_FIELD *field)
+{
+ uint length= column_names ? field->name_length : 0;
+
+ if (quick)
+ length= max(length, field->length);
+ else
+ length= max(length, field->max_length);
+
+ if (length < 4 && !IS_NOT_NULL(field->flags))
+ length= 4; /* Room for "NULL" */
+
+ return length;
+}
+
+/**
+ For a new result, return the max number of characters that any
+ upcoming row may return.
+
+ @param result Pointer to the result to judge
+
+ @returns The max number of characters in any row of this result
+*/
+static int get_result_width(MYSQL_RES *result)
+{
+ unsigned int len= 0;
+ MYSQL_FIELD *field;
+ MYSQL_FIELD_OFFSET offset;
+
+#ifndef DBUG_OFF
+ offset= mysql_field_tell(result);
+ DBUG_ASSERT(offset == 0);
+#else
+ offset= 0;
+#endif
+
+ while ((field= mysql_fetch_field(result)) != NULL)
+ len+= get_field_disp_length(field) + 3; /* plus bar, space, & final space */
+
+ (void) mysql_field_seek(result, offset);
+
+ return len + 1; /* plus final bar. */
+}
static void
tee_print_sized_data(const char *data, unsigned int data_length, unsigned int total_bytes_to_send, bool right_justified)
@@ -3596,7 +3648,7 @@ static void print_warnings()
mysql_store_result_for_lazy(&result);
/* Bail out when no warnings */
- if (!(num_rows= mysql_num_rows(result)))
+ if (!result || !(num_rows= mysql_num_rows(result)))
goto end;
cur= mysql_fetch_row(result);
@@ -4249,6 +4301,8 @@ sql_real_connect(char *host,char *database,char *user,char *password,
mysql_close(&mysql);
}
mysql_init(&mysql);
+ if (opt_init_command)
+ mysql_options(&mysql, MYSQL_INIT_COMMAND, opt_init_command);
if (opt_connect_timeout)
{
uint timeout=opt_connect_timeout;
@@ -4261,7 +4315,7 @@ sql_real_connect(char *host,char *database,char *user,char *password,
mysql_options(&mysql, MYSQL_SECURE_AUTH, (char *) &opt_secure_auth);
if (using_opt_local_infile)
mysql_options(&mysql,MYSQL_OPT_LOCAL_INFILE, (char*) &opt_local_infile);
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
@@ -4282,8 +4336,9 @@ sql_real_connect(char *host,char *database,char *user,char *password,
select_limit,max_join_size);
mysql_options(&mysql, MYSQL_INIT_COMMAND, init_command);
}
- if (default_charset_used)
- mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
+
+ mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
+
if (!mysql_real_connect(&mysql, host, user, password,
database, opt_mysql_port, opt_mysql_unix_port,
connect_flag | CLIENT_MULTI_STATEMENTS))
@@ -4298,6 +4353,9 @@ sql_real_connect(char *host,char *database,char *user,char *password,
}
return -1; // Retryable
}
+
+ charset_info= mysql.charset;
+
connected=1;
#ifndef EMBEDDED_LIBRARY
mysql.reconnect= debug_info_flag; // We want to know if this happens
@@ -4378,12 +4436,12 @@ com_status(String *buffer __attribute__((unused)),
mysql_free_result(result);
}
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
if ((status_str= mysql_get_ssl_cipher(&mysql)))
tee_fprintf(stdout, "SSL:\t\t\tCipher in use is %s\n",
status_str);
else
-#endif /* HAVE_OPENSSL */
+#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
tee_puts("SSL:\t\t\tNot in use", stdout);
if (skip_updates)
@@ -4920,17 +4978,3 @@ static int com_prompt(String *buffer, char *line)
tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
return 0;
}
-
-#ifndef EMBEDDED_LIBRARY
-/* Keep sql_string library happy */
-
-void *sql_alloc(size_t Size)
-{
- return my_malloc(Size,MYF(MY_WME));
-}
-
-void sql_element_free(void *ptr)
-{
- my_free(ptr,MYF(0));
-}
-#endif /* EMBEDDED_LIBRARY */