diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/Makefile.am | 10 | ||||
-rw-r--r-- | client/mysql.cc | 130 | ||||
-rw-r--r-- | client/mysql_upgrade.c | 42 | ||||
-rw-r--r-- | client/mysqladmin.cc | 11 | ||||
-rw-r--r-- | client/mysqlbinlog.cc | 67 | ||||
-rw-r--r-- | client/mysqlcheck.c | 6 | ||||
-rw-r--r-- | client/mysqldump.c | 77 | ||||
-rw-r--r-- | client/mysqlimport.c | 19 | ||||
-rw-r--r-- | client/mysqlshow.c | 2 | ||||
-rw-r--r-- | client/mysqlslap.c | 10 | ||||
-rw-r--r-- | client/mysqltest.cc | 38 |
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[] = { "<", "<", ">", ">", "\"", """, + /* Turn \0 into a space. Why not �? 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 |