summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/Makefile.am10
-rw-r--r--client/mysql.cc130
-rw-r--r--client/mysql_upgrade.c42
-rw-r--r--client/mysqladmin.cc11
-rw-r--r--client/mysqlbinlog.cc67
-rw-r--r--client/mysqlcheck.c6
-rw-r--r--client/mysqldump.c77
-rw-r--r--client/mysqlimport.c19
-rw-r--r--client/mysqlshow.c2
-rw-r--r--client/mysqlslap.c10
-rw-r--r--client/mysqltest.cc38
11 files changed, 294 insertions, 118 deletions
diff --git a/client/Makefile.am b/client/Makefile.am
index 94db565ba37..ccd0d8aada0 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -71,7 +71,7 @@ mysqldump_SOURCES= mysqldump.c \
$(top_srcdir)/mysys/mf_getdate.c
mysqlimport_SOURCES= mysqlimport.c
-
+mysqlimport_CFLAGS= -DTHREAD -UUNDEF_THREADS_HACK
mysqlimport_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
@CLIENT_EXTRA_LDFLAGS@ \
$(LIBMYSQLCLIENT_LA) \
@@ -80,14 +80,14 @@ mysqlimport_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
mysqlshow_SOURCES= mysqlshow.c
mysqlslap_SOURCES= mysqlslap.c
-mysqlslap_CFLAGS= -DTHREAD -UUNDEF_THREADS_HACK
+mysqlslap_CFLAGS= -DTHREAD -UMYSQL_CLIENT_NO_THREADS
mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
@CLIENT_EXTRA_LDFLAGS@ \
$(LIBMYSQLCLIENT_LA) \
$(top_builddir)/mysys/libmysys.a
mysqltest_SOURCES= mysqltest.cc
-mysqltest_CXXFLAGS= -DTHREAD -UUNDEF_THREADS_HACK
+mysqltest_CXXFLAGS= -DTHREAD -UMYSQL_CLIENT_NO_THREADS
mysqltest_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
@CLIENT_EXTRA_LDFLAGS@ \
$(LIBMYSQLCLIENT_LA) \
@@ -99,9 +99,9 @@ mysql_upgrade_SOURCES= mysql_upgrade.c \
$(top_srcdir)/mysys/my_getpagesize.c
# Fix for mit-threads
-DEFS = -DUNDEF_THREADS_HACK \
+DEFS = -DMYSQL_CLIENT_NO_THREADS \
-DDEFAULT_MYSQL_HOME="\"$(prefix)\"" \
- -DDATADIR="\"$(localstatedir)\""
+ -DMYSQL_DATADIR="\"$(localstatedir)\""
sql_src=log_event.h mysql_priv.h rpl_constants.h \
rpl_utility.h rpl_tblmap.h rpl_tblmap.cc \
diff --git a/client/mysql.cc b/client/mysql.cc
index 860fc3a5f6e..dc7022a0ffa 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -115,7 +115,7 @@ extern "C" {
#define PROMPT_CHAR '\\'
#define DEFAULT_DELIMITER ";"
-#define MAX_BATCH_BUFFER_SIZE (1024L * 1024L)
+#define MAX_BATCH_BUFFER_SIZE (1024L * 1024L * 1024L)
typedef struct st_status
{
@@ -170,6 +170,8 @@ static const char *xmlmeta[] = {
"<", "&lt;",
">", "&gt;",
"\"", "&quot;",
+ /* Turn \0 into a space. Why not &#0;? That's not valid XML or HTML. */
+ "\0", " ",
0, 0
};
static const char *day_names[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
@@ -1979,7 +1981,7 @@ static COMMANDS *find_command(char *name,char cmd_char)
*/
if (strstr(name, "\\g") || (strstr(name, delimiter) &&
!(strlen(name) >= 9 &&
- !my_strnncoll(charset_info,
+ !my_strnncoll(&my_charset_latin1,
(uchar*) name, 9,
(const uchar*) "delimiter",
9))))
@@ -2000,11 +2002,11 @@ static COMMANDS *find_command(char *name,char cmd_char)
{
if (commands[i].func &&
((name &&
- !my_strnncoll(charset_info,(uchar*)name,len,
+ !my_strnncoll(&my_charset_latin1, (uchar*)name, len,
(uchar*)commands[i].name,len) &&
!commands[i].name[len] &&
(!end || (end && commands[i].takes_params))) ||
- !name && commands[i].cmd_char == cmd_char))
+ (!name && commands[i].cmd_char == cmd_char)))
{
DBUG_PRINT("exit",("found command: %s", commands[i].name));
DBUG_RETURN(&commands[i]);
@@ -2163,7 +2165,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
buffer.length(0);
}
else if (!*ml_comment && (!*in_string && (inchar == '#' ||
- inchar == '-' && pos[1] == '-' &&
+ (inchar == '-' && pos[1] == '-' &&
/*
The third byte is either whitespace or is the
end of the line -- which would occur only
@@ -2171,7 +2173,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
itself whitespace and should also match.
*/
(my_isspace(charset_info,pos[2]) ||
- !pos[2]))))
+ !pos[2])))))
{
// Flush previously accepted characters
if (out != line)
@@ -2302,8 +2304,10 @@ extern "C" char **new_mysql_completion (const char *text, int start, int end);
*/
#if defined(USE_NEW_READLINE_INTERFACE)
+static int fake_magic_space(int, int);
extern "C" char *no_completion(const char*,int)
#elif defined(USE_LIBEDIT_INTERFACE)
+static int fake_magic_space(const char *, int);
extern "C" int no_completion(const char*,int)
#else
extern "C" char *no_completion()
@@ -2380,6 +2384,18 @@ static int not_in_history(const char *line)
return 1;
}
+
+#if defined(USE_NEW_READLINE_INTERFACE)
+static int fake_magic_space(int, int)
+#else
+static int fake_magic_space(const char *, int)
+#endif
+{
+ rl_insert(1, ' ');
+ return 0;
+}
+
+
static void initialize_readline (char *name)
{
/* Allow conditional parsing of the ~/.inputrc file. */
@@ -2389,12 +2405,15 @@ static void initialize_readline (char *name)
#if defined(USE_NEW_READLINE_INTERFACE)
rl_attempted_completion_function= (rl_completion_func_t*)&new_mysql_completion;
rl_completion_entry_function= (rl_compentry_func_t*)&no_completion;
+
+ rl_add_defun("magic-space", (rl_command_func_t *)&fake_magic_space, -1);
#elif defined(USE_LIBEDIT_INTERFACE)
#ifdef HAVE_LOCALE_H
setlocale(LC_ALL,""); /* so as libedit use isprint */
#endif
rl_attempted_completion_function= (CPPFunction*)&new_mysql_completion;
rl_completion_entry_function= &no_completion;
+ rl_add_defun("magic-space", (Function*)&fake_magic_space, -1);
#else
rl_attempted_completion_function= (CPPFunction*)&new_mysql_completion;
rl_completion_entry_function= &no_completion;
@@ -2732,7 +2751,7 @@ static int com_server_help(String *buffer __attribute__((unused)),
{
MYSQL_ROW cur;
const char *server_cmd= buffer->ptr();
- char cmd_buf[100];
+ char cmd_buf[100 + 1];
MYSQL_RES *result;
int error;
@@ -3308,6 +3327,9 @@ print_table_data(MYSQL_RES *result)
uint visible_length;
uint extra_padding;
+ if (off)
+ (void) tee_fputs(" ", PAGER);
+
if (cur[off] == NULL)
{
buffer= "NULL";
@@ -3342,7 +3364,7 @@ print_table_data(MYSQL_RES *result)
else
tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, FALSE);
}
- tee_fputs(" | ", PAGER);
+ tee_fputs(" |", PAGER);
}
(void) tee_fputs("\n", PAGER);
}
@@ -3482,11 +3504,29 @@ print_table_data_vertically(MYSQL_RES *result)
mysql_field_seek(result,0);
tee_fprintf(PAGER,
"*************************** %d. row ***************************\n", row_count);
+
+ ulong *lengths= mysql_fetch_lengths(result);
+
for (uint off=0; off < mysql_num_fields(result); off++)
{
field= mysql_fetch_field(result);
tee_fprintf(PAGER, "%*s: ",(int) max_length,field->name);
- tee_fprintf(PAGER, "%s\n",cur[off] ? (char*) cur[off] : "NULL");
+ if (cur[off])
+ {
+ unsigned int i;
+ const char *p;
+
+ for (i= 0, p= cur[off]; i < lengths[off]; i+= 1, p+= 1)
+ {
+ if (*p == '\0')
+ tee_putc((int)' ', PAGER);
+ else
+ tee_putc((int)*p, PAGER);
+ }
+ tee_putc('\n', PAGER);
+ }
+ else
+ tee_fprintf(PAGER, "NULL\n");
}
}
}
@@ -3553,7 +3593,7 @@ xmlencode_print(const char *src, uint length)
tee_fputs("NULL", PAGER);
else
{
- for (const char *p = src; *p && length; *p++, length--)
+ for (const char *p = src; length; *p++, length--)
{
const char *t;
if ((t = array_value(xmlmeta, *p)))
@@ -3573,7 +3613,12 @@ safe_put_field(const char *pos,ulong length)
else
{
if (opt_raw_data)
- tee_fputs(pos, PAGER);
+ {
+ unsigned long i;
+ /* Can't use tee_fputs(), it stops with NUL characters. */
+ for (i= 0; i < length; i++, pos++)
+ tee_putc(*pos, PAGER);
+ }
else for (const char *end=pos+length ; pos != end ; pos++)
{
#ifdef USE_MB
@@ -4264,41 +4309,36 @@ com_status(String *buffer __attribute__((unused)),
MYSQL_RES *result;
LINT_INIT(result);
+ if (mysql_real_query_for_lazy(
+ C_STRING_WITH_LEN("select DATABASE(), USER() limit 1")))
+ return 0;
+
tee_puts("--------------", stdout);
usage(1); /* Print version */
- if (connected)
+ tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",mysql_thread_id(&mysql));
+ /*
+ Don't remove "limit 1",
+ it is protection againts SQL_SELECT_LIMIT=0
+ */
+ if (mysql_store_result_for_lazy(&result))
{
- tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",mysql_thread_id(&mysql));
- /*
- Don't remove "limit 1",
- it is protection againts SQL_SELECT_LIMIT=0
- */
- if (!mysql_query(&mysql,"select DATABASE(), USER() limit 1") &&
- (result=mysql_use_result(&mysql)))
+ MYSQL_ROW cur=mysql_fetch_row(result);
+ if (cur)
{
- MYSQL_ROW cur=mysql_fetch_row(result);
- if (cur)
- {
- tee_fprintf(stdout, "Current database:\t%s\n", cur[0] ? cur[0] : "");
- tee_fprintf(stdout, "Current user:\t\t%s\n", cur[1]);
- }
- mysql_free_result(result);
- }
-#ifdef HAVE_OPENSSL
- 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 */
- tee_puts("SSL:\t\t\tNot in use", stdout);
+ tee_fprintf(stdout, "Current database:\t%s\n", cur[0] ? cur[0] : "");
+ tee_fprintf(stdout, "Current user:\t\t%s\n", cur[1]);
+ }
+ mysql_free_result(result);
}
+
+#ifdef HAVE_OPENSSL
+ if ((status_str= mysql_get_ssl_cipher(&mysql)))
+ tee_fprintf(stdout, "SSL:\t\t\tCipher in use is %s\n",
+ status_str);
else
- {
- vidattr(A_BOLD);
- tee_fprintf(stdout, "\nNo connection\n");
- vidattr(A_NORMAL);
- return 0;
- }
+#endif /* HAVE_OPENSSL */
+ tee_puts("SSL:\t\t\tNot in use", stdout);
+
if (skip_updates)
{
vidattr(A_BOLD);
@@ -4317,8 +4357,14 @@ com_status(String *buffer __attribute__((unused)),
tee_fprintf(stdout, "Insert id:\t\t%s\n", llstr(id, buff));
/* "limit 1" is protection against SQL_SELECT_LIMIT=0 */
- if (!mysql_query(&mysql,"select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1") &&
- (result=mysql_use_result(&mysql)))
+ if (mysql_real_query_for_lazy(C_STRING_WITH_LEN(
+ "select @@character_set_client, @@character_set_connection, "
+ "@@character_set_server, @@character_set_database limit 1")))
+ {
+ if (mysql_errno(&mysql) == CR_SERVER_GONE_ERROR)
+ return 0;
+ }
+ if (mysql_store_result_for_lazy(&result))
{
MYSQL_ROW cur=mysql_fetch_row(result);
if (cur)
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index cbc60d8acad..645fb037647 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -39,6 +39,7 @@ static uint my_end_arg= 0;
static char *opt_user= (char*)"root";
static DYNAMIC_STRING ds_args;
+static DYNAMIC_STRING conn_args;
static char *opt_password= 0;
static my_bool tty_password= 0;
@@ -135,6 +136,7 @@ static void free_used_memory(void)
free_defaults(defaults_argv);
dynstr_free(&ds_args);
+ dynstr_free(&conn_args);
}
@@ -204,7 +206,7 @@ static void add_one_option(DYNAMIC_STRING* ds,
}
}
dynstr_append_os_quoted(ds, "--", opt->name, eq, arg, NullS);
- dynstr_append(&ds_args, " ");
+ dynstr_append(ds, " ");
}
@@ -232,7 +234,7 @@ get_one_option(int optid, const struct my_option *opt,
case 'p':
if (argument == disabled_my_option)
- argument= (char*) ""; // Don't require password
+ argument= (char*) ""; /* Don't require password */
tty_password= 1;
add_option= FALSE;
if (argument)
@@ -251,11 +253,24 @@ get_one_option(int optid, const struct my_option *opt,
break;
case 'b': /* --basedir */
- case 'v': /* --verbose */
case 'd': /* --datadir */
+ fprintf(stderr, "%s: the '--%s' option is always ignored\n",
+ my_progname, optid == 'b' ? "basedir" : "datadir");
+ /* FALLTHROUGH */
+
+ case 'v': /* --verbose */
case 'f': /* --force */
add_option= FALSE;
break;
+
+ case 'h': /* --host */
+ case 'W': /* --pipe */
+ case 'P': /* --port */
+ case 'S': /* --socket */
+ case OPT_MYSQL_PROTOCOL: /* --protocol */
+ case OPT_SHARED_MEMORY_BASE_NAME: /* --shared-memory-base-name */
+ add_one_option(&conn_args, opt, argument);
+ break;
}
if (add_option)
@@ -604,13 +619,27 @@ static void create_mysql_upgrade_info_file(void)
/*
+ Print connection-related arguments.
+*/
+
+static void print_conn_args(const char *tool_name)
+{
+ if (conn_args.str[0])
+ verbose("Running '%s' with connection arguments: %s", tool_name,
+ conn_args.str);
+ else
+ verbose("Running '%s with default connection arguments", tool_name);
+}
+
+
+/*
Check and upgrade(if neccessary) all tables
in the server using "mysqlcheck --check-upgrade .."
*/
static int run_mysqlcheck_upgrade(void)
{
- verbose("Running 'mysqlcheck'...");
+ print_conn_args("mysqlcheck");
return run_tool(mysqlcheck_path,
NULL, /* Send output from mysqlcheck directly to screen */
"--no-defaults",
@@ -624,7 +653,7 @@ static int run_mysqlcheck_upgrade(void)
static int run_mysqlcheck_fixnames(void)
{
- verbose("Running 'mysqlcheck'...");
+ print_conn_args("mysqlcheck");
return run_tool(mysqlcheck_path,
NULL, /* Send output from mysqlcheck directly to screen */
"--no-defaults",
@@ -753,7 +782,8 @@ int main(int argc, char **argv)
strncpy(self_name, argv[0], FN_REFLEN);
}
- if (init_dynamic_string(&ds_args, "", 512, 256))
+ if (init_dynamic_string(&ds_args, "", 512, 256) ||
+ init_dynamic_string(&conn_args, "", 512, 256))
die("Out of memory");
load_defaults("my", load_default_groups, &argc, &argv);
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index 9865b67bb3b..a4e7c5ad0c9 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -24,7 +24,7 @@
#include <mysql.h>
#define ADMIN_VERSION "8.42"
-#define MAX_MYSQL_VAR 256
+#define MAX_MYSQL_VAR 512
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3
@@ -371,7 +371,7 @@ int main(int argc,char *argv[])
}
else
{
- while (!interrupted && (!opt_count_iterations || nr_iterations))
+ while (!interrupted)
{
new_line = 0;
if ((error=execute_commands(&mysql,argc,commands)))
@@ -395,11 +395,11 @@ int main(int argc,char *argv[])
}
if (interval)
{
+ if (opt_count_iterations && --nr_iterations == 0)
+ break;
sleep(interval);
if (new_line)
puts("");
- if (opt_count_iterations)
- nr_iterations--;
}
else
break;
@@ -743,6 +743,9 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
mysql_error(mysql));
return -1;
}
+
+ DBUG_ASSERT(mysql_num_rows(res) < MAX_MYSQL_VAR);
+
if (!opt_vertical)
print_header(res);
else
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 2cf91ec7da5..82af7ca65f6 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -17,10 +17,8 @@
TODO: print the catalog (some USE catalog.db ????).
- Standalone program to read a MySQL binary log (or relay log);
- can read files produced by 3.23, 4.x, 5.0 servers.
+ Standalone program to read a MySQL binary log (or relay log).
- Can read binlogs from 3.23/4.x/5.0 and relay logs from 4.x/5.0.
Should be able to read any file of these categories, even with
--start-position.
An important fact: the Format_desc event of the log is at most the 3rd event
@@ -681,6 +679,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
{
char ll_buff[21];
Log_event_type ev_type= ev->get_type_code();
+ my_bool destroy_evt= TRUE;
DBUG_ENTER("process_event");
print_event_info->short_form= short_form;
Exit_status retval= OK_CONTINUE;
@@ -689,8 +688,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
Format events are not concerned by --offset and such, we always need to
read them to be able to process the wanted events.
*/
- if ((rec_count >= offset) &&
- ((my_time_t)(ev->when) >= start_datetime) ||
+ if (((rec_count >= offset) &&
+ ((my_time_t)(ev->when) >= start_datetime)) ||
(ev_type == FORMAT_DESCRIPTION_EVENT))
{
if (ev_type != FORMAT_DESCRIPTION_EVENT)
@@ -871,12 +870,63 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
break;
}
case TABLE_MAP_EVENT:
+ {
+ Table_map_log_event *map= ((Table_map_log_event *)ev);
+ if (shall_skip_database(map->get_db_name()))
+ {
+ print_event_info->m_table_map_ignored.set_table(map->get_table_id(), map);
+ destroy_evt= FALSE;
+ goto end;
+ }
+ }
case WRITE_ROWS_EVENT:
case DELETE_ROWS_EVENT:
case UPDATE_ROWS_EVENT:
case PRE_GA_WRITE_ROWS_EVENT:
case PRE_GA_DELETE_ROWS_EVENT:
case PRE_GA_UPDATE_ROWS_EVENT:
+ {
+ if (ev_type != TABLE_MAP_EVENT)
+ {
+ Rows_log_event *e= (Rows_log_event*) ev;
+ Table_map_log_event *ignored_map=
+ print_event_info->m_table_map_ignored.get_table(e->get_table_id());
+ bool skip_event= (ignored_map != NULL);
+
+ /*
+ end of statement check:
+ i) destroy/free ignored maps
+ ii) if skip event, flush cache now
+ */
+ if (e->get_flags(Rows_log_event::STMT_END_F))
+ {
+ /*
+ Now is safe to clear ignored map (clear_tables will also
+ delete original table map events stored in the map).
+ */
+ if (print_event_info->m_table_map_ignored.count() > 0)
+ print_event_info->m_table_map_ignored.clear_tables();
+
+ /*
+ One needs to take into account an event that gets
+ filtered but was last event in the statement. If this is
+ the case, previous rows events that were written into
+ IO_CACHEs still need to be copied from cache to
+ result_file (as it would happen in ev->print(...) if
+ event was not skipped).
+ */
+ if (skip_event)
+ {
+ if ((copy_event_cache_to_file_and_reinit(&print_event_info->head_cache, result_file) ||
+ copy_event_cache_to_file_and_reinit(&print_event_info->body_cache, result_file)))
+ goto err;
+ }
+ }
+
+ /* skip the event check */
+ if (skip_event)
+ goto end;
+ }
/*
These events must be printed in base64 format, if printed.
base64 format requires a FD event to be safe, so if no FD
@@ -900,6 +950,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
goto err;
}
/* FALL THROUGH */
+ }
default:
ev->print(result_file, print_event_info);
}
@@ -919,7 +970,8 @@ end:
{
if (remote_opt)
ev->temp_buf= 0;
- delete ev;
+ if (destroy_evt) /* destroy it later if not set (ignored table map) */
+ delete ev;
}
DBUG_RETURN(retval);
}
@@ -934,10 +986,13 @@ static struct my_option my_long_options[] =
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"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' disables it and works only for binlogs without "
"row-based events; 'auto' is the default and prints base64 only when "
"necessary (i.e., for row-based events and format description events); "
+ "'decode-rows' suppresses BINLOG statements for row events, but does "
+ "not exit as an error if a row event is found, unlike 'never'; "
"'always' prints base64 whenever possible. 'always' is for debugging "
"only and should not be used in a production system. The default is "
"'auto'. --base64-output is a short form for --base64-output=always."
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index 1bdb28f5a11..82aabd77b24 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -287,7 +287,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'p':
if (argument == disabled_my_option)
- argument= (char*) ""; // Don't require password
+ argument= (char*) ""; /* Don't require password */
if (argument)
{
char *start = argument;
@@ -442,7 +442,7 @@ static int process_selected_tables(char *db, char **table_names, int tables)
{
if (use_db(db))
return 1;
- if (opt_all_in_1)
+ if (opt_all_in_1 && what_to_do != DO_UPGRADE)
{
/*
We need table list in form `a`, `b`, `c`
@@ -536,7 +536,7 @@ static int process_all_tables_in_db(char *database)
num_columns= mysql_num_fields(res);
- if (opt_all_in_1)
+ if (opt_all_in_1 && what_to_do != DO_UPGRADE)
{
/*
We need table list in form `a`, `b`, `c`
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 323376dd8bf..cac27424d6e 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -703,7 +703,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
#endif
case 'p':
if (argument == disabled_my_option)
- argument= (char*) ""; // Don't require password
+ argument= (char*) ""; /* Don't require password */
if (argument)
{
char *start=argument;
@@ -1397,18 +1397,19 @@ static char *cover_definer_clause_in_sp(const char *def_str,
SYNOPSIS
open_sql_file_for_table
name name of the table or view
+ flags flags (as per "man 2 open")
RETURN VALUES
0 Failed to open file
> 0 Handle of the open file
*/
-static FILE* open_sql_file_for_table(const char* table)
+static FILE* open_sql_file_for_table(const char* table, int flags)
{
FILE* res;
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
convert_dirname(tmp_path,path,NullS);
res= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
- O_WRONLY, MYF(MY_WME));
+ flags, MYF(MY_WME));
return res;
}
@@ -2290,7 +2291,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
if (path)
{
- if (!(sql_file= open_sql_file_for_table(table)))
+ if (!(sql_file= open_sql_file_for_table(table, O_WRONLY)))
DBUG_RETURN(0);
write_header(sql_file, db);
@@ -2501,7 +2502,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
{
if (path)
{
- if (!(sql_file= open_sql_file_for_table(table)))
+ if (!(sql_file= open_sql_file_for_table(table, O_WRONLY)))
DBUG_RETURN(0);
write_header(sql_file, db);
}
@@ -2725,12 +2726,10 @@ continue_xml:
DBUG_RETURN((uint) num_fields);
} /* get_table_structure */
-static void dump_trigger_old(MYSQL_RES *show_triggers_rs,
+static void dump_trigger_old(FILE *sql_file, MYSQL_RES *show_triggers_rs,
MYSQL_ROW *show_trigger_row,
const char *table_name)
{
- FILE *sql_file= md_result_file;
-
char quoted_table_name_buf[NAME_LEN * 2 + 3];
char *quoted_table_name= quote_name(table_name, quoted_table_name_buf, 1);
@@ -2796,11 +2795,10 @@ static void dump_trigger_old(MYSQL_RES *show_triggers_rs,
DBUG_VOID_RETURN;
}
-static int dump_trigger(MYSQL_RES *show_create_trigger_rs,
+static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs,
const char *db_name,
const char *db_cl_name)
{
- FILE *sql_file= md_result_file;
MYSQL_ROW row;
int db_cl_altered= FALSE;
@@ -2864,22 +2862,28 @@ static int dump_triggers_for_table(char *table_name, char *db_name)
uint old_opt_compatible_mode= opt_compatible_mode;
MYSQL_RES *show_triggers_rs;
MYSQL_ROW row;
+ FILE *sql_file= md_result_file;
char db_cl_name[MY_CS_NAME_SIZE];
+ int ret= TRUE;
DBUG_ENTER("dump_triggers_for_table");
DBUG_PRINT("enter", ("db: %s, table_name: %s", db_name, table_name));
+ if (path && !(sql_file= open_sql_file_for_table(table_name,
+ O_WRONLY | O_APPEND)))
+ DBUG_RETURN(1);
+
/* Do not use ANSI_QUOTES on triggers in dump */
opt_compatible_mode&= ~MASK_ANSI_QUOTES;
/* Get database collation. */
if (switch_character_set_results(mysql, "binary"))
- DBUG_RETURN(TRUE);
+ goto done;
if (fetch_db_collation(db_name, db_cl_name, sizeof (db_cl_name)))
- DBUG_RETURN(TRUE);
+ goto done;
/* Get list of triggers. */
@@ -2888,7 +2892,7 @@ static int dump_triggers_for_table(char *table_name, char *db_name)
quote_for_like(table_name, name_buff));
if (mysql_query_with_error_report(mysql, &show_triggers_rs, query_buff))
- DBUG_RETURN(TRUE);
+ goto done;
/* Dump triggers. */
@@ -2909,17 +2913,15 @@ static int dump_triggers_for_table(char *table_name, char *db_name)
provide all the necessary information to restore trigger properly.
*/
- dump_trigger_old(show_triggers_rs, &row, table_name);
+ dump_trigger_old(sql_file, show_triggers_rs, &row, table_name);
}
else
{
MYSQL_RES *show_create_trigger_rs= mysql_store_result(mysql);
if (!show_create_trigger_rs ||
- dump_trigger(show_create_trigger_rs, db_name, db_cl_name))
- {
- DBUG_RETURN(TRUE);
- }
+ dump_trigger(sql_file, show_create_trigger_rs, db_name, db_cl_name))
+ goto done;
mysql_free_result(show_create_trigger_rs);
}
@@ -2929,7 +2931,7 @@ static int dump_triggers_for_table(char *table_name, char *db_name)
mysql_free_result(show_triggers_rs);
if (switch_character_set_results(mysql, default_charset))
- DBUG_RETURN(TRUE);
+ goto done;
/*
make sure to set back opt_compatible mode to
@@ -2937,7 +2939,13 @@ static int dump_triggers_for_table(char *table_name, char *db_name)
*/
opt_compatible_mode=old_opt_compatible_mode;
- DBUG_RETURN(FALSE);
+ ret= FALSE;
+
+done:
+ if (path)
+ my_fclose(sql_file, MYF(0));
+
+ DBUG_RETURN(ret);
}
static void add_load_option(DYNAMIC_STRING *str, const char *option,
@@ -3129,6 +3137,12 @@ static void dump_table(char *table, char *db)
dynstr_append_checked(&query_string, filename);
dynstr_append_checked(&query_string, "'");
+ 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 */
+ default_charset);
+ dynstr_append_checked(&query_string, " */");
+
if (fields_terminated || enclosed || opt_enclosed || escaped)
dynstr_append_checked(&query_string, " FIELDS");
@@ -3813,6 +3827,10 @@ static int dump_all_databases()
return 1;
while ((row= mysql_fetch_row(tableres)))
{
+ if (mysql_get_server_version(mysql) >= 50003 &&
+ !my_strcasecmp(&my_charset_latin1, row[0], "information_schema"))
+ continue;
+
if (dump_all_tables_in_db(row[0]))
result=1;
}
@@ -3827,6 +3845,10 @@ static int dump_all_databases()
}
while ((row= mysql_fetch_row(tableres)))
{
+ if (mysql_get_server_version(mysql) >= 50003 &&
+ !my_strcasecmp(&my_charset_latin1, row[0], "information_schema"))
+ continue;
+
if (dump_all_views_in_db(row[0]))
result=1;
}
@@ -3933,10 +3955,6 @@ int init_dumping_tables(char *qdatabase)
static int init_dumping(char *database, int init_func(char*))
{
- if (mysql_get_server_version(mysql) >= 50003 &&
- !my_strcasecmp(&my_charset_latin1, database, "information_schema"))
- return 1;
-
if (mysql_select_db(mysql, database))
{
DB_error(mysql, "when selecting the database");
@@ -3995,6 +4013,7 @@ static int dump_all_tables_in_db(char *database)
DBUG_RETURN(1);
if (opt_xml)
print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS);
+
if (lock_tables)
{
DYNAMIC_STRING query;
@@ -4228,7 +4247,10 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
}
end= pos;
- if (lock_tables)
+ /* Can't LOCK TABLES in INFORMATION_SCHEMA, so don't try. */
+ if (lock_tables &&
+ !(mysql_get_server_version(mysql) >= 50003 &&
+ !my_strcasecmp(&my_charset_latin1, db, "information_schema")))
{
if (mysql_real_query(mysql, lock_tables_query.str,
lock_tables_query.length-1))
@@ -4782,7 +4804,7 @@ static my_bool get_view_structure(char *table, char* db)
/* If requested, open separate .sql file for this view */
if (path)
{
- if (!(sql_file= open_sql_file_for_table(table)))
+ if (!(sql_file= open_sql_file_for_table(table, O_WRONLY)))
DBUG_RETURN(1);
write_header(sql_file, db);
@@ -4794,7 +4816,8 @@ static my_bool get_view_structure(char *table, char* db)
result_table);
check_io(sql_file);
}
- fprintf(sql_file, "/*!50001 DROP TABLE %s*/;\n", opt_quoted_table);
+ /* Table might not exist if this view was dumped with --tab. */
+ fprintf(sql_file, "/*!50001 DROP TABLE IF EXISTS %s*/;\n", opt_quoted_table);
if (opt_drop)
{
fprintf(sql_file, "/*!50001 DROP VIEW IF EXISTS %s*/;\n",
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index ec418244f3d..92e9702aea0 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -222,7 +222,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
#endif
case 'p':
if (argument == disabled_my_option)
- argument= (char*) ""; // Don't require password
+ argument= (char*) ""; /* Don't require password */
if (argument)
{
char *start=argument;
@@ -303,7 +303,8 @@ static int get_options(int *argc, char ***argv)
static int write_to_table(char *filename, MYSQL *mysql)
{
char tablename[FN_REFLEN], hard_path[FN_REFLEN],
- sql_statement[FN_REFLEN*16+256], *end;
+ escaped_name[FN_REFLEN * 2 + 1],
+ sql_statement[FN_REFLEN*16+256], *end, *pos;
DBUG_ENTER("write_to_table");
DBUG_PRINT("enter",("filename: %s",filename));
@@ -338,15 +339,25 @@ static int write_to_table(char *filename, MYSQL *mysql)
fprintf(stdout, "Loading data from SERVER file: %s into %s\n",
hard_path, tablename);
}
+ mysql_real_escape_string(mysql, escaped_name, hard_path,
+ (unsigned long) strlen(hard_path));
sprintf(sql_statement, "LOAD DATA %s %s INFILE '%s'",
opt_low_priority ? "LOW_PRIORITY" : "",
- opt_local_file ? "LOCAL" : "", hard_path);
+ opt_local_file ? "LOCAL" : "", escaped_name);
end= strend(sql_statement);
if (replace)
end= strmov(end, " REPLACE");
if (ignore)
end= strmov(end, " IGNORE");
- end= strmov(strmov(end, " INTO TABLE "), tablename);
+ end= strmov(end, " INTO TABLE `");
+ /* Turn any ` into `` in table name. */
+ for (pos= tablename; *pos; pos++)
+ {
+ if (*pos == '`')
+ *end++= '`';
+ *end++= *pos;
+ }
+ end= strmov(end, "`");
if (fields_terminated || enclosed || opt_enclosed || escaped)
end= strmov(end, " FIELDS");
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index e401d6cad8f..15f791ca8fb 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -282,7 +282,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'p':
if (argument == disabled_my_option)
- argument= (char*) ""; // Don't require password
+ argument= (char*) ""; /* Don't require password */
if (argument)
{
char *start=argument;
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
index 4cf8c7204ed..70abfbb7136 100644
--- a/client/mysqlslap.c
+++ b/client/mysqlslap.c
@@ -565,8 +565,7 @@ static struct my_option my_long_options[] =
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"csv", OPT_SLAP_CSV,
"Generate CSV output to named file or to stdout if no file is named.",
- (uchar**) &opt_csv_str, (uchar**) &opt_csv_str, 0, GET_STR,
- OPT_ARG, 0, 0, 0, 0, 0, 0},
+ NULL, NULL, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#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},
@@ -713,7 +712,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'p':
if (argument == disabled_my_option)
- argument= (char*) ""; // Don't require password
+ argument= (char*) ""; /* Don't require password */
if (argument)
{
char *start= argument;
@@ -740,6 +739,11 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
DBUG_PUSH(argument ? argument : default_dbug_option);
debug_check_flag= 1;
break;
+ case OPT_SLAP_CSV:
+ if (!argument)
+ argument= (char *)"-"; /* use stdout */
+ opt_csv_str= argument;
+ break;
#include <sslopt-case.h>
case 'V':
print_version();
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 7965dafb863..5eb79aecc23 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -1463,34 +1463,38 @@ static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...)
Test if diff is present. This is needed on Windows systems
as the OS returns 1 whether diff is successful or if it is
not present.
- Takes name of diff program as argument
-
+
We run diff -v and look for output in stdout.
We don't redirect stderr to stdout to make for a simplified check
Windows will output '"diff"' is not recognized... to stderr if it is
not present.
*/
-int diff_check (const char *diff_name)
+#ifdef __WIN__
+
+static int diff_check(const char *diff_name)
{
- char buf[512]= {0};
- FILE *res_file;
- char cmd[128];
- my_snprintf (cmd, sizeof(cmd), "%s -v", diff_name);
- int have_diff = 0;
+ FILE *res_file;
+ char buf[128];
+ int have_diff= 0;
- if (!(res_file= popen(cmd, "r")))
- die("popen(\"%s\", \"r\") failed", cmd);
+ my_snprintf(buf, sizeof(buf), "%s -v", diff_name);
- /* if diff is not present, nothing will be in stdout to increment have_diff */
- if (fgets(buf, sizeof(buf), res_file))
- {
- have_diff += 1;
- }
- pclose(res_file);
- return have_diff;
+ if (!(res_file= popen(buf, "r")))
+ die("popen(\"%s\", \"r\") failed", buf);
+
+ /* if diff is not present, nothing will be in stdout to increment have_diff */
+ if (fgets(buf, sizeof(buf), res_file))
+ have_diff= 1;
+
+ pclose(res_file);
+
+ return have_diff;
}
+#endif
+
+
/*
Show the diff of two files using the systems builtin diff
command. If no such diff command exist, just dump the content