diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/.cvsignore | 14 | ||||
-rwxr-xr-x | client/CMakeLists.txt | 27 | ||||
-rw-r--r-- | client/client_priv.h | 28 | ||||
-rw-r--r-- | client/mysql.cc | 126 | ||||
-rw-r--r-- | client/mysql_upgrade.c | 29 | ||||
-rw-r--r-- | client/mysqladmin.cc | 51 | ||||
-rw-r--r-- | client/mysqlbinlog.cc | 5 | ||||
-rw-r--r-- | client/mysqlcheck.c | 30 | ||||
-rw-r--r-- | client/mysqldump.c | 428 | ||||
-rw-r--r-- | client/mysqlimport.c | 19 | ||||
-rw-r--r-- | client/mysqlshow.c | 6 | ||||
-rw-r--r-- | client/mysqlslap.c | 24 | ||||
-rw-r--r-- | client/mysqltest.cc | 293 | ||||
-rw-r--r-- | client/readline.cc | 2 | ||||
-rw-r--r-- | client/sql_string.cc | 3 | ||||
-rw-r--r-- | client/sql_string.h | 4 |
16 files changed, 736 insertions, 353 deletions
diff --git a/client/.cvsignore b/client/.cvsignore deleted file mode 100644 index 54bbaed97f5..00000000000 --- a/client/.cvsignore +++ /dev/null @@ -1,14 +0,0 @@ -.deps -.libs -Makefile -Makefile.in -insert_test -mysql -mysql-test -mysql_test -mysqladmin -mysqldump -mysqlimport -mysqlshow -select_test -thread_test diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index e96437d40d0..28e4c354a69 100755 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -14,13 +14,6 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake") -# We use the "mysqlclient_notls" library here just as safety, in case -# any of the clients here would go beyond the client API and access the -# Thread Local Storage directly. - -SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") -SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") - INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib ${CMAKE_SOURCE_DIR}/extra/yassl/include @@ -30,27 +23,27 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/strings) ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c) -TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32) +TARGET_LINK_LIBRARIES(mysql mysqlclient) ADD_EXECUTABLE(mysqltest mysqltest.cc) SET_SOURCE_FILES_PROPERTIES(mysqltest.cc PROPERTIES COMPILE_FLAGS "-DTHREADS") -TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys regex wsock32 dbug) +TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys regex dbug) ADD_EXECUTABLE(mysqlcheck mysqlcheck.c) -TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient_notls wsock32) +TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient) ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c ../mysys/mf_getdate.c) -TARGET_LINK_LIBRARIES(mysqldump mysqlclient_notls wsock32) +TARGET_LINK_LIBRARIES(mysqldump mysqlclient) ADD_EXECUTABLE(mysqlimport mysqlimport.c) -TARGET_LINK_LIBRARIES(mysqlimport mysqlclient_notls wsock32) +TARGET_LINK_LIBRARIES(mysqlimport mysqlclient) ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c ../mysys/my_getpagesize.c) -TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient_notls wsock32) +TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient) ADD_DEPENDENCIES(mysql_upgrade GenFixPrivs) ADD_EXECUTABLE(mysqlshow mysqlshow.c) -TARGET_LINK_LIBRARIES(mysqlshow mysqlclient_notls wsock32) +TARGET_LINK_LIBRARIES(mysqlshow mysqlclient) ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc ../mysys/mf_tempdir.c @@ -59,14 +52,14 @@ ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc ../mysys/my_bitmap.c ../mysys/my_vle.c ../mysys/base64.c) -TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient_notls wsock32) +TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient) ADD_EXECUTABLE(mysqladmin mysqladmin.cc) -TARGET_LINK_LIBRARIES(mysqladmin mysqlclient_notls wsock32) +TARGET_LINK_LIBRARIES(mysqladmin mysqlclient) ADD_EXECUTABLE(mysqlslap mysqlslap.c) SET_SOURCE_FILES_PROPERTIES(mysqlslap.c PROPERTIES COMPILE_FLAGS "-DTHREADS") -TARGET_LINK_LIBRARIES(mysqlslap mysqlclient mysys zlib wsock32 dbug) +TARGET_LINK_LIBRARIES(mysqlslap mysqlclient mysys zlib dbug) ADD_EXECUTABLE(echo echo.c) diff --git a/client/client_priv.h b/client/client_priv.h index 06145232995..97a8920f744 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2006 MySQL AB +/* Copyright (C) 2001-2006 MySQL AB, 2009 Sun Microsystems, Inc This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -62,6 +62,9 @@ enum options_client OPT_MYSQL_NUMBER_OF_QUERY, OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE, OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_CREATE_SLAP_SCHEMA, + OPT_MYSQLDUMP_SLAVE_APPLY, + OPT_MYSQLDUMP_SLAVE_DATA, + OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT, OPT_SLAP_CSV, OPT_SLAP_CREATE_STRING, OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE, OPT_SLAP_AUTO_GENERATE_WRITE_NUM, OPT_SLAP_AUTO_GENERATE_ADD_AUTO, @@ -78,7 +81,30 @@ enum options_client OPT_SLAP_DETACH, OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT_MODE, OPT_SERVER_ID, OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT, + OPT_AUTO_VERTICAL_OUTPUT, OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE, OPT_WRITE_BINLOG, OPT_DUMP_DATE, + OPT_INIT_COMMAND, OPT_MAX_CLIENT_OPTION }; + +/** + First mysql version supporting the information schema. +*/ +#define FIRST_INFORMATION_SCHEMA_VERSION 50003 + +/** + Name of the information schema database. +*/ +#define INFORMATION_SCHEMA_DB_NAME "information_schema" + +/** + First mysql version supporting the performance schema. +*/ +#define FIRST_PERFORMANCE_SCHEMA_VERSION 50600 + +/** + Name of the performance schema database. +*/ +#define PERFORMANCE_SCHEMA_DB_NAME "performance_schema" + diff --git a/client/mysql.cc b/client/mysql.cc index 9d078153a33..be3c13bf362 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -141,8 +141,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; @@ -155,7 +156,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; @@ -184,6 +186,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; @@ -237,6 +240,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. */ @@ -1064,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[]) { @@ -1113,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)) { @@ -1143,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) @@ -1156,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(), @@ -1328,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, @@ -1345,6 +1375,9 @@ static struct my_option my_long_options[] = {"no-auto-rehash", 'A', "No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead.", 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.", + (uchar**) &auto_vertical_output, (uchar**) &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}, {"character-sets-dir", OPT_CHARSETS_DIR, @@ -1398,6 +1431,10 @@ static struct my_option my_long_options[] = {"ignore-spaces", 'i', "Ignore space after function names.", (uchar**) &ignore_spaces, (uchar**) &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.", + (uchar**) &opt_init_command, (uchar**) &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.", (uchar**) &opt_local_infile, (uchar**) &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, @@ -1590,9 +1627,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) { @@ -1797,10 +1831,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); @@ -2928,7 +2958,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); @@ -3055,7 +3084,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); @@ -3386,6 +3415,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) @@ -4217,6 +4305,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; @@ -4250,8 +4340,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)) @@ -4266,6 +4357,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 diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 52c3636219d..4c4820e69eb 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -34,7 +34,8 @@ static char mysql_path[FN_REFLEN]; static char mysqlcheck_path[FN_REFLEN]; -static my_bool opt_force, opt_verbose, debug_info_flag, debug_check_flag; +static my_bool opt_force, opt_verbose, debug_info_flag, debug_check_flag, + opt_systables_only; static uint my_end_arg= 0; static char *opt_user= (char*)"root"; @@ -121,6 +122,10 @@ static struct my_option my_long_options[]= #include <sslopt-longopts.h> {"tmpdir", 't', "Directory for temporary files", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"upgrade-system-tables", 's', "Only upgrade the system tables " + "do not try to upgrade the data.", + (uchar**)&opt_systables_only, (uchar**)&opt_systables_only, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"user", 'u', "User for login if not current user.", (uchar**) &opt_user, (uchar**) &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"verbose", 'v', "Display more output about the process", @@ -778,6 +783,10 @@ static int run_sql_fix_privilege_tables(void) found_real_errors++; print_line(line); } + else if (strncmp(line, "WARNING", 7) == 0) + { + print_line(line); + } } while ((line= get_line(line)) && *line); } @@ -814,7 +823,8 @@ int main(int argc, char **argv) init_dynamic_string(&conn_args, "", 512, 256)) die("Out of memory"); - load_defaults("my", load_default_groups, &argc, &argv); + if (load_defaults("my", load_default_groups, &argc, &argv)) + die(NULL); defaults_argv= argv; /* Must be freed by 'free_defaults' */ if (handle_options(&argc, &argv, my_long_options, get_one_option)) @@ -838,8 +848,15 @@ int main(int argc, char **argv) /* Find mysql */ find_tool(mysql_path, IF_WIN("mysql.exe", "mysql"), self_name); - /* Find mysqlcheck */ - find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck"), self_name); + if (!opt_systables_only) + { + /* Find mysqlcheck */ + find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck"), self_name); + } + else + { + printf("The --upgrade-system-tables option was used, databases won't be touched.\n"); + } /* Read the mysql_upgrade_info file to check if mysql_upgrade @@ -856,8 +873,8 @@ int main(int argc, char **argv) /* Run "mysqlcheck" and "mysql_fix_privilege_tables.sql" */ - if (run_mysqlcheck_fixnames() || - run_mysqlcheck_upgrade() || + if ((!opt_systables_only && + (run_mysqlcheck_fixnames() || run_mysqlcheck_upgrade())) || run_sql_fix_privilege_tables()) { /* diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 2b93c149523..2c4a20f2786 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -30,7 +30,7 @@ #define MAX_TRUNC_LENGTH 3 char *host= NULL, *user= 0, *opt_password= 0, - *default_charset= NULL; + *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME; char truncated_var_names[MAX_MYSQL_VAR][MAX_TRUNC_LENGTH]; char ex_var_names[MAX_MYSQL_VAR][FN_REFLEN]; ulonglong last_values[MAX_MYSQL_VAR]; @@ -304,7 +304,8 @@ int main(int argc,char *argv[]) MY_INIT(argv[0]); mysql_init(&mysql); - load_defaults("my",load_default_groups,&argc,&argv); + if (load_defaults("my",load_default_groups,&argc,&argv)) + exit(1); save_argv = argv; /* Save for free_defaults */ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) { @@ -325,8 +326,8 @@ int main(int argc,char *argv[]) if (tty_password) opt_password = get_tty_password(NullS); - VOID(signal(SIGINT,endprog)); /* Here if abort */ - VOID(signal(SIGTERM,endprog)); /* Here if abort */ + (void) signal(SIGINT,endprog); /* Here if abort */ + (void) signal(SIGTERM,endprog); /* Here if abort */ if (opt_compress) mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS); @@ -348,8 +349,7 @@ int main(int argc,char *argv[]) if (shared_memory_base_name) mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); #endif - if (default_charset) - mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset); + mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset); error_flags= (myf)(opt_nobeep ? 0 : ME_BELL); if (sql_connect(&mysql, option_wait)) @@ -901,23 +901,38 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { char buff[128],crypted_pw[64]; time_t start_time; + char *typed_password= NULL, *verified= NULL; /* Do initialization the same way as we do in mysqld */ start_time=time((time_t*) 0); randominit(&rand_st,(ulong) start_time,(ulong) start_time/2); - if (argc < 2) + if (argc < 1) { my_printf_error(0, "Too few arguments to change password", error_flags); return 1; } - if (argv[1][0]) + else if (argc == 1) + { + /* prompt for password */ + typed_password= get_tty_password("New password: "); + verified= get_tty_password("Confirm new password: "); + if (strcmp(typed_password, verified) != 0) + { + my_printf_error(0,"Passwords don't match",MYF(ME_BELL)); + return -1; + } + } + else + typed_password= argv[1]; + + if (typed_password[0]) { - char *pw= argv[1]; bool old= (find_type(argv[0], &command_typelib, 2) == ADMIN_OLD_PASSWORD); #ifdef __WIN__ - uint pw_len= (uint) strlen(pw); - if (pw_len > 1 && pw[0] == '\'' && pw[pw_len-1] == '\'') + size_t pw_len= strlen(typed_password); + if (pw_len > 1 && typed_password[0] == '\'' && + typed_password[pw_len-1] == '\'') printf("Warning: single quotes were not trimmed from the password by" " your command\nline client, as you might have expected.\n"); #endif @@ -955,9 +970,9 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } } if (old) - make_scrambled_password_323(crypted_pw, pw); + make_scrambled_password_323(crypted_pw, typed_password); else - make_scrambled_password(crypted_pw, pw); + make_scrambled_password(crypted_pw, typed_password); } else crypted_pw[0]=0; /* No password */ @@ -992,6 +1007,12 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) return -1; } } + /* free up memory from prompted password */ + if (typed_password != argv[1]) + { + my_free(typed_password,MYF(MY_ALLOW_ZERO_PTR)); + my_free(verified,MYF(MY_ALLOW_ZERO_PTR)); + } argc--; argv++; break; } @@ -1083,8 +1104,8 @@ static void usage(void) kill id,id,... Kill mysql threads"); #if MYSQL_VERSION_ID >= 32200 puts("\ - password new-password Change old password to new-password, MySQL 4.1 hashing.\n\ - old-password new-password Change old password to new-password in old format.\n"); + password [new-password] Change old password to new-password in current format\n\ + old-password [new-password] Change old password to new-password in old format"); #endif puts("\ ping Check if mysqld is alive\n\ diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 32945f0cf89..dae6b36eeb2 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -1942,7 +1942,7 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, return ERROR_STOP; } #endif - if (init_io_cache(file, fileno(stdin), 0, READ_CACHE, (my_off_t) 0, + if (init_io_cache(file, my_fileno(stdin), 0, READ_CACHE, (my_off_t) 0, 0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE))) { error("Failed to init IO cache."); @@ -2031,7 +2031,8 @@ int main(int argc, char** argv) my_init_time(); // for time functions - load_defaults("my", load_default_groups, &argc, &argv); + if (load_defaults("my", load_default_groups, &argc, &argv)) + exit(1); defaults_argv= argv; parse_args(&argc, (char***)&argv); diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 1533e602639..57fa5b6a0f1 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2009 Sun Microsystems, Inc This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -128,7 +128,7 @@ static struct my_option my_long_options[] = "Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"write-binlog", OPT_WRITE_BINLOG, - "Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Enabled by default; use --skip-write-binlog when commands should not be sent to replication slaves.", + "Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Use --skip-write-binlog when commands should not be sent to replication slaves.", (uchar**) &opt_write_binlog, (uchar**) &opt_write_binlog, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"optimize", 'o', "Optimize table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, @@ -344,9 +344,8 @@ static int get_options(int *argc, char ***argv) exit(0); } - load_defaults("my", load_default_groups, argc, argv); - - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + if ((ho_error= load_defaults("my", load_default_groups, argc, argv)) || + (ho_error=handle_options(argc, argv, my_long_options, get_one_option))) exit(ho_error); if (!what_to_do) @@ -369,12 +368,15 @@ static int get_options(int *argc, char ***argv) If there's no --default-character-set option given with --fix-table-name or --fix-db-name set the default character set to "utf8". */ - if (!default_charset && (opt_fix_db_names || opt_fix_table_names)) + if (!default_charset) { - default_charset= (char*) "utf8"; + if (opt_fix_db_names || opt_fix_table_names) + default_charset= (char*) "utf8"; + else + default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME; } - if (default_charset && !get_charset_by_csname(default_charset, MY_CS_PRIMARY, - MYF(MY_WME))) + if (strcmp(default_charset, MYSQL_AUTODETECT_CHARSET_NAME) && + !get_charset_by_csname(default_charset, MY_CS_PRIMARY, MYF(MY_WME))) { printf("Unsupported character set: %s\n", default_charset); return 1; @@ -641,8 +643,11 @@ static int process_one_db(char *database) static int use_db(char *database) { - if (mysql_get_server_version(sock) >= 50003 && - !my_strcasecmp(&my_charset_latin1, database, "information_schema")) + if (mysql_get_server_version(sock) >= FIRST_INFORMATION_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, database, INFORMATION_SCHEMA_DB_NAME)) + return 1; + if (mysql_get_server_version(sock) >= FIRST_PERFORMANCE_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, database, PERFORMANCE_SCHEMA_DB_NAME)) return 1; if (mysql_select_db(sock, database)) { @@ -798,8 +803,7 @@ static int dbConnect(char *host, char *user, char *passwd) if (shared_memory_base_name) mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); #endif - if (default_charset) - mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset); + mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset); if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd, NULL, opt_mysql_port, opt_mysql_unix_port, 0))) { diff --git a/client/mysqldump.c b/client/mysqldump.c index e9e3124b9cb..9c665e6d76a 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -98,6 +98,8 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_complete_insert= 0, opt_drop_database= 0, opt_replace_into= 0, opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1, + opt_slave_apply= 0, + opt_include_master_host_port= 0, opt_events= 0, opt_alltspcs=0, opt_notspcs= 0; static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0; @@ -118,7 +120,10 @@ static my_bool server_supports_switching_charsets= TRUE; static ulong opt_compatible_mode= 0; #define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1 #define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2 +#define MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL 1 +#define MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL 2 static uint opt_mysql_port= 0, opt_master_data; +static uint opt_slave_data; static uint my_end_arg; static char * opt_mysql_unix_port=0; static int first_error=0; @@ -206,6 +211,10 @@ static struct my_option my_long_options[] = {"allow-keywords", OPT_KEYWORDS, "Allow creation of column names that are keywords.", (uchar**) &opt_keywords, (uchar**) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"apply-slave-statements", OPT_MYSQLDUMP_SLAVE_APPLY, + "Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.", + (uchar**) &opt_slave_apply, (uchar**) &opt_slave_apply, 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, #ifdef __NETWARE__ {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -264,6 +273,19 @@ static struct my_option my_long_options[] = {"disable-keys", 'K', "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (uchar**) &opt_disable_keys, (uchar**) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + {"dump-slave", OPT_MYSQLDUMP_SLAVE_DATA, + "This causes the binary log position and filename of the master to be " + "appended to the dumped data output. Setting the value to 1, will print" + "it as a CHANGE MASTER command in the dumped data output; if equal" + " to 2, that command will be prefixed with a comment symbol. " + "This option will turn --lock-all-tables on, unless " + "--single-transaction is specified too (in which case a " + "global read lock is only taken a short time at the beginning of the dump " + "- don't forget to read about --single-transaction below). In all cases " + "any action on logs will happen at the exact moment of the dump." + "Option automatically turns --lock-tables off.", + (uchar**) &opt_slave_data, (uchar**) &opt_slave_data, 0, + GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0}, {"events", 'E', "Dump events.", (uchar**) &opt_events, (uchar**) &opt_events, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -317,6 +339,12 @@ static struct my_option my_long_options[] = "use the directive multiple times, once for each table. Each table must " "be specified with both database and table names, e.g. --ignore-table=database.table", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"include-master-host-port", OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT, + "Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' in dump produced with --dump-slave.", + (uchar**) &opt_include_master_host_port, + (uchar**) &opt_include_master_host_port, + 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, {"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.", (uchar**) &opt_ignore, (uchar**) &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -402,7 +430,7 @@ static struct my_option my_long_options[] = (uchar**) &opt_routines, (uchar**) &opt_routines, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"set-charset", OPT_SET_CHARSET, - "Add 'SET NAMES default_character_set' to the output. Enabled by default; suppress with --skip-set-charset.", + "Add 'SET NAMES default_character_set' to the output.", (uchar**) &opt_set_charset, (uchar**) &opt_set_charset, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"set-variable", 'O', @@ -764,6 +792,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), if (!argument) /* work like in old versions */ opt_master_data= MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL; break; + case (int) OPT_MYSQLDUMP_SLAVE_DATA: + if (!argument) /* work like in old versions */ + opt_slave_data= MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL; + break; case (int) OPT_OPTIMIZE: extended_insert= opt_drop= opt_lock= quick= create_options= opt_disable_keys= lock_tables= opt_set_charset= 1; @@ -858,12 +890,13 @@ static int get_options(int *argc, char ***argv) opt_net_buffer_length= *mysql_params->p_net_buffer_length; md_result_file= stdout; - load_defaults("my",load_default_groups,argc,argv); + if (load_defaults("my",load_default_groups,argc,argv)) + return 1; defaults_argv= *argv; - if (hash_init(&ignore_table, charset_info, 16, 0, 0, - (hash_get_key) get_table_key, - (hash_free_key) free_table_ent, 0)) + if (my_hash_init(&ignore_table, charset_info, 16, 0, 0, + (my_hash_get_key) get_table_key, + (my_hash_free_key) free_table_ent, 0)) return(EX_EOM); /* Don't copy internal log tables */ if (my_hash_insert(&ignore_table, @@ -896,6 +929,14 @@ static int get_options(int *argc, char ***argv) return(EX_USAGE); } + /* We don't delete master logs if slave data option */ + if (opt_slave_data) + { + opt_lock_all_tables= !opt_single_transaction; + opt_master_data= 0; + opt_delete_master_logs= 0; + } + /* Ensure consistency of the set of binlog & locking options */ if (opt_delete_master_logs && !opt_master_data) opt_master_data= MYSQL_OPT_MASTER_DATA_COMMENTED_SQL; @@ -906,7 +947,10 @@ static int get_options(int *argc, char ***argv) return(EX_USAGE); } if (opt_master_data) + { opt_lock_all_tables= !opt_single_transaction; + opt_slave_data= 0; + } if (opt_single_transaction || opt_lock_all_tables) lock_tables= 0; if (enclosed && opt_enclosed) @@ -1273,120 +1317,68 @@ static int switch_character_set_results(MYSQL *mysql, const char *cs_name) } /** - Rewrite CREATE TRIGGER statement, enclosing DEFINER clause in - version-specific comment. - - This function parses the CREATE TRIGGER statement and encloses - DEFINER-clause in version-specific comment: - input query: CREATE DEFINER=a@b TRIGGER ... - rewritten query: CREATE * / / *!50017 DEFINER=a@b * / / *!50003 TRIGGER ... - - @note This function will go away when WL#3995 is implemented. - - @param[in] trigger_def_str CREATE TRIGGER statement string. - @param[in] trigger_def_length length of the trigger_def_str. - - @return pointer to the new allocated query string. -*/ - -static char *cover_definer_clause_in_trigger(const char *trigger_def_str, - uint trigger_def_length) -{ - char *query_str= NULL; - char *definer_begin= my_case_str(trigger_def_str, trigger_def_length, - C_STRING_WITH_LEN(" DEFINER")); - char *definer_end; - - if (!definer_begin) - return NULL; - - definer_end= my_case_str(definer_begin, strlen(definer_begin), - C_STRING_WITH_LEN(" TRIGGER")); - - if (definer_end) - { - char *query_str_tail; - - /* - Allocate memory for new query string: original string - from SHOW statement and version-specific comments. - */ - query_str= alloc_query_str(trigger_def_length + 23); - - query_str_tail= strnmov(query_str, - trigger_def_str, - definer_begin - trigger_def_str); - - query_str_tail= strmov(query_str_tail, - "*/ /*!50017"); - - query_str_tail= strnmov(query_str_tail, - definer_begin, - definer_end - definer_begin); + Rewrite statement, enclosing DEFINER clause in version-specific comment. - query_str_tail= strxmov(query_str_tail, - "*/ /*!50003", - definer_end, - NullS); - } - - return query_str; -} - -/** - Rewrite CREATE FUNCTION or CREATE PROCEDURE statement, enclosing DEFINER - clause in version-specific comment. - - This function parses the CREATE FUNCTION | PROCEDURE statement and - encloses DEFINER-clause in version-specific comment: + This function parses any CREATE statement and encloses DEFINER-clause in + version-specific comment: input query: CREATE DEFINER=a@b FUNCTION ... rewritten query: CREATE * / / *!50020 DEFINER=a@b * / / *!50003 FUNCTION ... @note This function will go away when WL#3995 is implemented. - @param[in] def_str CREATE FUNCTION|PROCEDURE statement string. - @param[in] def_str_length length of the def_str. + @param[in] stmt_str CREATE statement string. + @param[in] stmt_length Length of the stmt_str. + @param[in] definer_version_str Minimal MySQL version number when + DEFINER clause is supported in the + given statement. + @param[in] definer_version_length Length of definer_version_str. + @param[in] stmt_version_str Minimal MySQL version number when the + given statement is supported. + @param[in] stmt_version_length Length of stmt_version_str. + @param[in] keyword_str Keyword to look for after CREATE. + @param[in] keyword_length Length of keyword_str. @return pointer to the new allocated query string. */ -static char *cover_definer_clause_in_sp(const char *def_str, - uint def_str_length) +static char *cover_definer_clause(const char *stmt_str, + uint stmt_length, + const char *definer_version_str, + uint definer_version_length, + const char *stmt_version_str, + uint stmt_version_length, + const char *keyword_str, + uint keyword_length) { - char *query_str= NULL; - char *definer_begin= my_case_str(def_str, def_str_length, + char *definer_begin= my_case_str(stmt_str, stmt_length, C_STRING_WITH_LEN(" DEFINER")); - char *definer_end; + char *definer_end= NULL; + + char *query_str= NULL; + char *query_ptr; if (!definer_begin) return NULL; definer_end= my_case_str(definer_begin, strlen(definer_begin), - C_STRING_WITH_LEN(" PROCEDURE")); + keyword_str, keyword_length); if (!definer_end) - { - definer_end= my_case_str(definer_begin, strlen(definer_begin), - C_STRING_WITH_LEN(" FUNCTION")); - } + return NULL; - if (definer_end) - { - char *query_str_tail; + /* + Allocate memory for new query string: original string + from SHOW statement and version-specific comments. + */ + query_str= alloc_query_str(stmt_length + 23); - /* - Allocate memory for new query string: original string - from SHOW statement and version-specific comments. - */ - query_str= alloc_query_str(def_str_length + 23); - - query_str_tail= strnmov(query_str, def_str, definer_begin - def_str); - query_str_tail= strmov(query_str_tail, "*/ /*!50020"); - query_str_tail= strnmov(query_str_tail, definer_begin, - definer_end - definer_begin); - query_str_tail= strxmov(query_str_tail, "*/ /*!50003", - definer_end, NullS); - } + query_ptr= strnmov(query_str, stmt_str, definer_begin - stmt_str); + query_ptr= strnmov(query_ptr, C_STRING_WITH_LEN("*/ /*!")); + query_ptr= strnmov(query_ptr, definer_version_str, definer_version_length); + query_ptr= strnmov(query_ptr, definer_begin, definer_end - definer_begin); + query_ptr= strnmov(query_ptr, C_STRING_WITH_LEN("*/ /*!")); + query_ptr= strnmov(query_ptr, stmt_version_str, stmt_version_length); + query_ptr= strxmov(query_ptr, definer_end, NullS); return query_str; } @@ -1419,8 +1411,8 @@ static void free_resources() if (md_result_file && md_result_file != stdout) my_fclose(md_result_file, MYF(0)); my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR)); - if (hash_inited(&ignore_table)) - hash_free(&ignore_table); + if (my_hash_inited(&ignore_table)) + my_hash_free(&ignore_table); if (extended_insert) dynstr_free(&extended_row); if (insert_pat_inited) @@ -1922,6 +1914,8 @@ static uint dump_events_for_db(char *db) */ if (strlen(row[3]) != 0) { + char *query_str; + if (opt_drop) fprintf(sql_file, "/*!50106 DROP EVENT IF EXISTS %s */%s\n", event_name, delimiter); @@ -1948,31 +1942,36 @@ static uint dump_events_for_db(char *db) row[4], /* character_set_results */ row[5]); /* collation_connection */ } - else - { - /* - mysqldump is being run against the server, that does not - provide character set information in SHOW CREATE - statements. + else + { + /* + mysqldump is being run against the server, that does not + provide character set information in SHOW CREATE + statements. - NOTE: the dump may be incorrect, since character set - information is required in order to restore event properly. - */ + NOTE: the dump may be incorrect, since character set + information is required in order to restore event properly. + */ - fprintf(sql_file, - "--\n" - "-- WARNING: old server version. " - "The following dump may be incomplete.\n" - "--\n"); - } + fprintf(sql_file, + "--\n" + "-- WARNING: old server version. " + "The following dump may be incomplete.\n" + "--\n"); + } switch_sql_mode(sql_file, delimiter, row[1]); switch_time_zone(sql_file, delimiter, row[2]); + query_str= cover_definer_clause(row[3], strlen(row[3]), + C_STRING_WITH_LEN("50117"), + C_STRING_WITH_LEN("50106"), + C_STRING_WITH_LEN(" EVENT")); + fprintf(sql_file, "/*!50106 %s */ %s\n", - (const char *) row[3], + (const char *) (query_str != NULL ? query_str : row[3]), (const char *) delimiter); restore_time_zone(sql_file, delimiter); @@ -2003,7 +2002,7 @@ static uint dump_events_for_db(char *db) mysql_free_result(event_list_res); if (lock_tables) - VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES")); + (void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"); DBUG_RETURN(0); } @@ -2127,7 +2126,16 @@ static uint dump_routines_for_db(char *db) fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */;\n", routine_type[i], routine_name); - query_str= cover_definer_clause_in_sp(row[2], strlen(row[2])); + query_str= cover_definer_clause(row[2], strlen(row[2]), + C_STRING_WITH_LEN("50020"), + C_STRING_WITH_LEN("50003"), + C_STRING_WITH_LEN(" FUNCTION")); + + if (!query_str) + query_str= cover_definer_clause(row[2], strlen(row[2]), + C_STRING_WITH_LEN("50020"), + C_STRING_WITH_LEN("50003"), + C_STRING_WITH_LEN(" PROCEDURE")); if (mysql_num_fields(routine_res) >= 6) { @@ -2197,7 +2205,7 @@ static uint dump_routines_for_db(char *db) DBUG_RETURN(1); if (lock_tables) - VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES")); + (void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"); DBUG_RETURN(0); } @@ -2806,8 +2814,10 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs, while ((row= mysql_fetch_row(show_create_trigger_rs))) { - char *query_str= cover_definer_clause_in_trigger(row[2], strlen(row[2])); - + char *query_str= cover_definer_clause(row[2], strlen(row[2]), + C_STRING_WITH_LEN("50017"), + C_STRING_WITH_LEN("50003"), + C_STRING_WITH_LEN(" TRIGGER")); if (switch_db_collation(sql_file, db_name, ";", db_cl_name, row[5], &db_cl_altered)) @@ -3316,7 +3326,7 @@ static void dump_table(char *table, char *db) { if (length) { - if (!IS_NUM_FIELD(field)) + if (!(field->flags & NUM_FLAG)) { /* "length * 2 + 2" is OK for both HEX and non-HEX modes: @@ -3384,7 +3394,7 @@ static void dump_table(char *table, char *db) } if (row[i]) { - if (!IS_NUM_FIELD(field)) + if (!(field->flags & NUM_FLAG)) { if (opt_xml) { @@ -3827,8 +3837,12 @@ 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")) + if (mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, row[0], INFORMATION_SCHEMA_DB_NAME)) + continue; + + if (mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME)) continue; if (dump_all_tables_in_db(row[0])) @@ -3845,8 +3859,12 @@ 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")) + if (mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, row[0], INFORMATION_SCHEMA_DB_NAME)) + continue; + + if (mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME)) continue; if (dump_all_views_in_db(row[0])) @@ -3992,7 +4010,7 @@ static int init_dumping(char *database, int init_func(char*)) my_bool include_table(const uchar *hash_key, size_t len) { - return !hash_search(&ignore_table, hash_key, len); + return ! my_hash_search(&ignore_table, hash_key, len); } @@ -4077,7 +4095,7 @@ static int dump_all_tables_in_db(char *database) check_io(md_result_file); } if (lock_tables) - VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES")); + (void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"); if (flush_privileges && using_mysql_db == 0) { fprintf(md_result_file,"\n--\n-- Flush Grant Tables \n--\n"); @@ -4151,7 +4169,7 @@ static my_bool dump_all_views_in_db(char *database) check_io(md_result_file); } if (lock_tables) - VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES")); + (void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"); return 0; } /* dump_all_tables_in_db */ @@ -4247,10 +4265,12 @@ static int dump_selected_tables(char *db, char **table_names, int tables) } end= pos; - /* Can't LOCK TABLES in INFORMATION_SCHEMA, so don't try. */ + /* Can't LOCK TABLES in I_S / P_S, so don't try. */ if (lock_tables && - !(mysql_get_server_version(mysql) >= 50003 && - !my_strcasecmp(&my_charset_latin1, db, "information_schema"))) + !(mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, db, INFORMATION_SCHEMA_DB_NAME)) && + !(mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, db, PERFORMANCE_SCHEMA_DB_NAME))) { if (mysql_real_query(mysql, lock_tables_query.str, lock_tables_query.length-1)) @@ -4323,7 +4343,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) check_io(md_result_file); } if (lock_tables) - VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES")); + (void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"); DBUG_RETURN(0); } /* dump_selected_tables */ @@ -4367,6 +4387,130 @@ static int do_show_master_status(MYSQL *mysql_con) return 0; } +static int do_stop_slave_sql(MYSQL *mysql_con) +{ + MYSQL_RES *slave; + /* We need to check if the slave sql is running in the first place */ + if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS")) + return(1); + else + { + MYSQL_ROW row= mysql_fetch_row(slave); + if (row && row[11]) + { + /* if SLAVE SQL is not running, we don't stop it */ + if (!strcmp(row[11],"No")) + { + mysql_free_result(slave); + /* Silently assume that they don't have the slave running */ + return(0); + } + } + } + mysql_free_result(slave); + + /* now, stop slave if running */ + if (mysql_query_with_error_report(mysql_con, 0, "STOP SLAVE SQL_THREAD")) + return(1); + + return(0); +} + +static int add_stop_slave(void) +{ + if (opt_comments) + fprintf(md_result_file, + "\n--\n-- stop slave statement to make a recovery dump)\n--\n\n"); + fprintf(md_result_file, "STOP SLAVE;\n"); + return(0); +} + +static int add_slave_statements(void) +{ + if (opt_comments) + fprintf(md_result_file, + "\n--\n-- start slave statement to make a recovery dump)\n--\n\n"); + fprintf(md_result_file, "START SLAVE;\n"); + return(0); +} + +static int do_show_slave_status(MYSQL *mysql_con) +{ + MYSQL_RES *slave; + const char *comment_prefix= + (opt_slave_data == MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : ""; + if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS")) + { + if (!ignore_errors) + { + /* SHOW SLAVE STATUS reports nothing and --force is not enabled */ + my_printf_error(0, "Error: Slave not set up", MYF(0)); + } + mysql_free_result(slave); + return 1; + } + else + { + MYSQL_ROW row= mysql_fetch_row(slave); + if (row && row[9] && row[21]) + { + /* SHOW MASTER STATUS reports file and position */ + if (opt_comments) + fprintf(md_result_file, + "\n--\n-- Position to start replication or point-in-time " + "recovery from (the master of this slave)\n--\n\n"); + + fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix); + + if (opt_include_master_host_port) + { + if (row[1]) + fprintf(md_result_file, "MASTER_HOST='%s', ", row[1]); + if (row[3]) + fprintf(md_result_file, "MASTER_PORT='%s', ", row[3]); + } + fprintf(md_result_file, + "MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]); + + check_io(md_result_file); + } + mysql_free_result(slave); + } + return 0; +} + +static int do_start_slave_sql(MYSQL *mysql_con) +{ + MYSQL_RES *slave; + /* We need to check if the slave sql is stopped in the first place */ + if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS")) + return(1); + else + { + MYSQL_ROW row= mysql_fetch_row(slave); + if (row && row[11]) + { + /* if SLAVE SQL is not running, we don't start it */ + if (!strcmp(row[11],"Yes")) + { + mysql_free_result(slave); + /* Silently assume that they don't have the slave running */ + return(0); + } + } + } + mysql_free_result(slave); + + /* now, start slave if stopped */ + if (mysql_query_with_error_report(mysql_con, 0, "START SLAVE")) + { + my_printf_error(0, "Error: Unable to start slave", MYF(0)); + return 1; + } + return(0); +} + + static int do_flush_tables_read_lock(MYSQL *mysql_con) { @@ -5029,6 +5173,9 @@ int main(int argc, char **argv) if (!path) write_header(md_result_file, *argv); + if (opt_slave_data && do_stop_slave_sql(mysql)) + goto err; + if ((opt_lock_all_tables || opt_master_data) && do_flush_tables_read_lock(mysql)) goto err; @@ -5047,8 +5194,13 @@ int main(int argc, char **argv) goto err; flush_logs= 0; /* not anymore; that would not be sensible */ } + /* Add 'STOP SLAVE to beginning of dump */ + if (opt_slave_apply && add_stop_slave()) + goto err; if (opt_master_data && do_show_master_status(mysql)) goto err; + if (opt_slave_data && do_show_slave_status(mysql)) + goto err; if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */ goto err; @@ -5076,6 +5228,14 @@ int main(int argc, char **argv) dump_databases(argv); } + /* if --dump-slave , start the slave sql thread */ + if (opt_slave_data && do_start_slave_sql(mysql)) + goto err; + + /* add 'START SLAVE' to end of dump */ + if (opt_slave_apply && add_slave_statements()) + goto err; + /* ensure dumped data flushed */ if (md_result_file && fflush(md_result_file)) { diff --git a/client/mysqlimport.c b/client/mysqlimport.c index ef38d760e5d..f8432c95548 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -55,11 +55,10 @@ static char *opt_password=0, *current_user=0, *current_host=0, *current_db=0, *fields_terminated=0, *lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0, *opt_columns=0, - *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME; + *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME; static uint opt_mysql_port= 0, opt_protocol= 0; static char * opt_mysql_unix_port=0; static longlong opt_ignore_lines= -1; -static CHARSET_INFO *charset_info= &my_charset_latin1; #include <sslopt-vars.h> #ifdef HAVE_SMEM @@ -282,10 +281,6 @@ static int get_options(int *argc, char ***argv) fprintf(stderr, "You can't use --ignore (-i) and --replace (-r) at the same time.\n"); return(1); } - 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 < 2) { usage(); @@ -440,6 +435,7 @@ static MYSQL *db_connect(char *host, char *database, if (shared_memory_base_name) mysql_options(mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); #endif + mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset); if (!(mysql_real_connect(mysql,host,user,passwd, database,opt_mysql_port,opt_mysql_unix_port, 0))) @@ -596,7 +592,8 @@ int main(int argc, char **argv) char **argv_to_free; MY_INIT(argv[0]); - load_defaults("my",load_default_groups,&argc,&argv); + if (load_defaults("my",load_default_groups,&argc,&argv)) + return 1; /* argv is changed in the program */ argv_to_free= argv; if (get_options(&argc, &argv)) @@ -614,8 +611,8 @@ int main(int argc, char **argv) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - VOID(pthread_mutex_init(&counter_mutex, NULL)); - VOID(pthread_cond_init(&count_threshhold, NULL)); + pthread_mutex_init(&counter_mutex, NULL); + pthread_cond_init(&count_threshhold, NULL); for (counter= 0; *argv != NULL; argv++) /* Loop through tables */ { @@ -654,8 +651,8 @@ int main(int argc, char **argv) pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime); } pthread_mutex_unlock(&counter_mutex); - VOID(pthread_mutex_destroy(&counter_mutex)); - VOID(pthread_cond_destroy(&count_threshhold)); + pthread_mutex_destroy(&counter_mutex); + pthread_cond_destroy(&count_threshhold); pthread_attr_destroy(&attr); } else diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 15f791ca8fb..588ee049546 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -32,7 +32,7 @@ static my_bool tty_password= 0, opt_table_type= 0; static my_bool debug_info_flag= 0, debug_check_flag= 0; static uint my_end_arg= 0; static uint opt_verbose=0; -static char *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME; +static char *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME; #ifdef HAVE_SMEM static char *shared_memory_base_name=0; @@ -63,7 +63,9 @@ int main(int argc, char **argv) char *wild; MYSQL mysql; MY_INIT(argv[0]); - load_defaults("my",load_default_groups,&argc,&argv); + if (load_defaults("my",load_default_groups,&argc,&argv)) + exit(1); + get_options(&argc,&argv); wild=0; diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 5983b911866..6ff2a868a21 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -299,7 +299,11 @@ int main(int argc, char **argv) MY_INIT(argv[0]); - 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,&argv)) { @@ -352,10 +356,10 @@ int main(int argc, char **argv) } } - VOID(pthread_mutex_init(&counter_mutex, NULL)); - VOID(pthread_cond_init(&count_threshhold, NULL)); - VOID(pthread_mutex_init(&sleeper_mutex, NULL)); - VOID(pthread_cond_init(&sleep_threshhold, NULL)); + pthread_mutex_init(&counter_mutex, NULL); + pthread_cond_init(&count_threshhold, NULL); + pthread_mutex_init(&sleeper_mutex, NULL); + pthread_cond_init(&sleep_threshhold, NULL); /* Main iterations loop */ eptr= engine_options; @@ -386,10 +390,10 @@ int main(int argc, char **argv) } while (eptr ? (eptr= eptr->next) : 0); - VOID(pthread_mutex_destroy(&counter_mutex)); - VOID(pthread_cond_destroy(&count_threshhold)); - VOID(pthread_mutex_destroy(&sleeper_mutex)); - VOID(pthread_cond_destroy(&sleep_threshhold)); + pthread_mutex_destroy(&counter_mutex); + pthread_cond_destroy(&count_threshhold); + pthread_mutex_destroy(&sleeper_mutex); + pthread_cond_destroy(&sleep_threshhold); if (!opt_only_print) mysql_close(&mysql); /* Close & free connection */ @@ -1204,7 +1208,7 @@ get_options(int *argc,char ***argv) if (opt_csv_str[0] == '-') { - csv_file= fileno(stdout); + csv_file= my_fileno(stdout); } else { diff --git a/client/mysqltest.cc b/client/mysqltest.cc index e0cdec42a60..79ee7fe9990 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -75,7 +75,8 @@ enum { OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION, OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL, - OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES + OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES, + OPT_RESULT_FORMAT_VERSION }; static int record= 0, opt_sleep= -1; @@ -88,6 +89,7 @@ const char *opt_logdir= ""; const char *opt_include= 0, *opt_charsets_dir; static int opt_port= 0; static int opt_max_connect_retries; +static int opt_result_format_version; static my_bool opt_compress= 0, silent= 0, verbose= 0; static my_bool debug_info_flag= 0, debug_check_flag= 0; static my_bool tty_password= 0; @@ -115,6 +117,8 @@ static uint my_end_arg= 0; /* Number of lines of the result to include in failure report */ static uint opt_tail_lines= 0; +static uint opt_connect_timeout= 0; + static char delimiter[MAX_DELIMITER_LENGTH]= ";"; static uint delimiter_length= 1; @@ -260,8 +264,7 @@ enum enum_commands { Q_SEND, Q_REAP, Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN, Q_PING, Q_EVAL, - Q_RPL_PROBE, Q_ENABLE_RPL_PARSE, - Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT, + Q_EVAL_RESULT, Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG, Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG, Q_WAIT_FOR_SLAVE_TO_STOP, @@ -283,11 +286,12 @@ enum enum_commands { Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR, Q_LIST_FILES, Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE, Q_SEND_SHUTDOWN, Q_SHUTDOWN_SERVER, - Q_MOVE_FILE, - + Q_RESULT_FORMAT_VERSION, + Q_MOVE_FILE, Q_SEND_EVAL, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ - Q_COMMENT_WITH_COMMAND + Q_COMMENT_WITH_COMMAND, + Q_EMPTY_LINE }; @@ -320,9 +324,6 @@ const char *command_names[]= "replace_column", "ping", "eval", - "rpl_probe", - "enable_rpl_parse", - "disable_rpl_parse", "eval_result", /* Enable/disable that the _query_ is logged to result file */ "enable_query_log", @@ -380,7 +381,9 @@ const char *command_names[]= "list_files_append_file", "send_shutdown", "shutdown_server", + "result_format", "move_file", + "send_eval", 0 }; @@ -662,14 +665,6 @@ public: LogFile log_file; LogFile progress_file; - -/* Disable functions that only exist in MySQL 4.0 */ -#if MYSQL_VERSION_ID < 40000 -void mysql_enable_rpl_parse(MYSQL* mysql __attribute__((unused))) {} -void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {} -int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; } -my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; } -#endif void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, int len); void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val); @@ -701,12 +696,12 @@ pthread_handler_t send_one_query(void *arg) struct st_connection *cn= (struct st_connection*)arg; mysql_thread_init(); - VOID(mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len)); + (void) mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len); mysql_thread_end(); pthread_mutex_lock(&cn->mutex); cn->query_done= 1; - VOID(pthread_cond_signal(&cn->cond)); + pthread_cond_signal(&cn->cond); pthread_mutex_unlock(&cn->mutex); pthread_exit(0); return 0; @@ -1138,7 +1133,7 @@ void free_used_memory() close_connections(); close_files(); - hash_free(&var_hash); + my_hash_free(&var_hash); for (i= 0 ; i < q_lines.elements ; i++) { @@ -1171,7 +1166,6 @@ void free_used_memory() mysql_server_end(); /* Don't use DBUG after mysql_server_end() */ - DBUG_VIOLATION_HELPER_LEAVE; return; } @@ -2001,8 +1995,8 @@ VAR* var_get(const char *var_name, const char **var_name_end, my_bool raw, if (length >= MAX_VAR_NAME_LENGTH) die("Too long variable name: %s", save_var_name); - if (!(v = (VAR*) hash_search(&var_hash, (const uchar*) save_var_name, - length))) + if (!(v = (VAR*) my_hash_search(&var_hash, (const uchar*) save_var_name, + length))) { char buff[MAX_VAR_NAME_LENGTH+1]; strmake(buff, save_var_name, length); @@ -2033,7 +2027,7 @@ err: VAR *var_obtain(const char *name, int len) { VAR* v; - if ((v = (VAR*)hash_search(&var_hash, (const uchar *) name, len))) + if ((v = (VAR*)my_hash_search(&var_hash, (const uchar *) name, len))) return v; v = var_init(0, name, len, "", 0); my_hash_insert(&var_hash, (uchar*)v); @@ -2203,6 +2197,59 @@ void var_query_set(VAR *var, const char *query, const char** query_end) } +static void +set_result_format_version(ulong new_version) +{ + switch (new_version){ + case 1: + /* The first format */ + break; + case 2: + /* New format that also writes comments and empty lines + from test file to result */ + break; + default: + die("Version format %lu has not yet been implemented", new_version); + break; + } + opt_result_format_version= new_version; +} + + +/* + Set the result format version to use when generating + the .result file +*/ + +static void +do_result_format_version(struct st_command *command) +{ + long version; + static DYNAMIC_STRING ds_version; + const struct command_arg result_format_args[] = { + "version", ARG_STRING, TRUE, &ds_version, "Version to use", + }; + + DBUG_ENTER("do_result_format_version"); + + check_command_args(command, command->first_argument, + result_format_args, + sizeof(result_format_args)/sizeof(struct command_arg), + ','); + + /* Convert version number to int */ + if (!str2int(ds_version.str, 10, (long) 0, (long) INT_MAX, &version)) + die("Invalid version number: '%s'", ds_version.str); + + set_result_format_version(version); + + dynstr_append(&ds_res, "result_format: "); + dynstr_append_mem(&ds_res, ds_version.str, ds_version.length); + dynstr_append(&ds_res, "\n"); + dynstr_free(&ds_version); +} + + /* Set variable from the result of a field in a query @@ -2967,6 +3014,7 @@ void do_move_file(struct st_command *command) void do_chmod_file(struct st_command *command) { long mode= 0; + int err_code; static DYNAMIC_STRING ds_mode; static DYNAMIC_STRING ds_file; const struct command_arg chmod_file_args[] = { @@ -2986,7 +3034,10 @@ void do_chmod_file(struct st_command *command) die("You must write a 4 digit octal number for mode"); DBUG_PRINT("info", ("chmod %o %s", (uint)mode, ds_file.str)); - handle_command_error(command, chmod(ds_file.str, mode)); + err_code= chmod(ds_file.str, mode); + if (err_code < 0) + err_code= 1; + handle_command_error(command, err_code); dynstr_free(&ds_mode); dynstr_free(&ds_file); DBUG_VOID_RETURN; @@ -3847,12 +3898,8 @@ int do_save_master_pos() MYSQL_ROW row; MYSQL *mysql = &cur_con->mysql; const char *query; - int rpl_parse; DBUG_ENTER("do_save_master_pos"); - rpl_parse = mysql_rpl_parse_enabled(mysql); - mysql_disable_rpl_parse(mysql); - #ifdef HAVE_NDB_BINLOG /* Wait for ndb binlog to be up-to-date with all changes @@ -4002,10 +4049,6 @@ int do_save_master_pos() strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1); master_pos.pos = strtoul(row[1], (char**) 0, 10); mysql_free_result(res); - - if (rpl_parse) - mysql_enable_rpl_parse(mysql); - DBUG_RETURN(0); } @@ -4068,29 +4111,6 @@ void do_let(struct st_command *command) } -int do_rpl_probe(struct st_command *command __attribute__((unused))) -{ - DBUG_ENTER("do_rpl_probe"); - if (mysql_rpl_probe(&cur_con->mysql)) - die("Failed in mysql_rpl_probe(): '%s'", mysql_error(&cur_con->mysql)); - DBUG_RETURN(0); -} - - -int do_enable_rpl_parse(struct st_command *command __attribute__((unused))) -{ - mysql_enable_rpl_parse(&cur_con->mysql); - return 0; -} - - -int do_disable_rpl_parse(struct st_command *command __attribute__((unused))) -{ - mysql_disable_rpl_parse(&cur_con->mysql); - return 0; -} - - /* Sleep the number of specified seconds @@ -5021,6 +5041,11 @@ void do_connect(struct st_command *command) #endif if (!mysql_init(&con_slot->mysql)) die("Failed on mysql_init()"); + + if (opt_connect_timeout) + mysql_options(&con_slot->mysql, MYSQL_OPT_CONNECT_TIMEOUT, + (void *) &opt_connect_timeout); + if (opt_compress || con_compress) mysql_options(&con_slot->mysql, MYSQL_OPT_COMPRESS, NullS); mysql_options(&con_slot->mysql, MYSQL_OPT_LOCAL_INFILE, 0); @@ -5305,7 +5330,7 @@ my_bool end_of_query(int c) int read_line(char *buf, int size) { - char c, UNINIT_VAR(last_quote); + char c, UNINIT_VAR(last_quote), last_char= 0; char *p= buf, *buf_end= buf + size - 1; int skip_char= 0; enum {R_NORMAL, R_Q, R_SLASH_IN_Q, @@ -5403,14 +5428,24 @@ int read_line(char *buf, int size) } else if (my_isspace(charset_info, c)) { - /* Skip all space at begining of line */ if (c == '\n') { + if (last_char == '\n') + { + /* Two new lines in a row, return empty line */ + DBUG_PRINT("info", ("Found two new lines in a row")); + *p++= c; + *p= 0; + DBUG_RETURN(0); + } + /* Query hasn't started yet */ start_lineno= cur_file->lineno; DBUG_PRINT("info", ("Query hasn't started yet, start_lineno: %d", start_lineno)); } + + /* Skip all space at begining of line */ skip_char= 1; } else if (end_of_query(c)) @@ -5451,6 +5486,8 @@ int read_line(char *buf, int size) } + last_char= c; + if (!skip_char) { /* Could be a multibyte character */ @@ -5660,9 +5697,10 @@ int read_command(struct st_command** command_ptr) DBUG_RETURN(1); } - convert_to_format_v1(read_command_buf); + if (opt_result_format_version == 1) + convert_to_format_v1(read_command_buf); - DBUG_PRINT("info", ("query: %s", read_command_buf)); + DBUG_PRINT("info", ("query: '%s'", read_command_buf)); if (*p == '#') { command->type= Q_COMMENT; @@ -5672,6 +5710,10 @@ int read_command(struct st_command** command_ptr) command->type= Q_COMMENT_WITH_COMMAND; p+= 2; /* Skip past -- */ } + else if (*p == '\n') + { + command->type= Q_EMPTY_LINE; + } /* Skip leading spaces */ while (*p && my_isspace(charset_info, *p)) @@ -5766,6 +5808,11 @@ static struct my_option my_long_options[] = {"result-file", 'R', "Read/Store result from/in this file.", (uchar**) &result_file_name, (uchar**) &result_file_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"result-format-version", OPT_RESULT_FORMAT_VERSION, + "Version of the result file format to use", + (uchar**) &opt_result_format_version, + (uchar**) &opt_result_format_version, 0, + GET_INT, REQUIRED_ARG, 1, 1, 2, 0, 0, 0}, {"server-arg", 'A', "Send option value to embedded server as a parameter.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"server-file", 'F', "Read embedded server arguments from file.", @@ -5810,6 +5857,11 @@ static struct my_option my_long_options[] = {"view-protocol", OPT_VIEW_PROTOCOL, "Use views for select", (uchar**) &view_protocol, (uchar**) &view_protocol, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"connect_timeout", OPT_CONNECT_TIMEOUT, + "Number of seconds before connection timeout.", + (uchar**) &opt_connect_timeout, + (uchar**) &opt_connect_timeout, 0, GET_UINT, REQUIRED_ARG, + 120, 0, 3600 * 12, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -5970,6 +6022,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), sf_malloc_quick=1; #endif break; + case OPT_RESULT_FORMAT_VERSION: + set_result_format_version(opt_result_format_version); + break; case 'V': print_version(); exit(0); @@ -5983,7 +6038,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), int parse_args(int argc, char **argv) { - load_defaults("my",load_default_groups,&argc,&argv); + if (load_defaults("my",load_default_groups,&argc,&argv)) + exit(1); + default_argv= argv; if ((handle_options(&argc, &argv, my_long_options, get_one_option))) @@ -6548,8 +6605,6 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, if (!disable_result_log) { - ulonglong UNINIT_VAR(affected_rows); /* Ok to be undef if 'disable_info' is set */ - if (res) { MYSQL_FIELD *fields= mysql_fetch_fields(res); @@ -6566,10 +6621,10 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, /* Need to call mysql_affected_rows() before the "new" - query to find the warnings + query to find the warnings. */ if (!disable_info) - affected_rows= mysql_affected_rows(mysql); + append_info(ds, mysql_affected_rows(mysql), mysql_info(mysql)); /* Add all warnings to the result. We can't do this if we are in @@ -6584,9 +6639,6 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, dynstr_append_mem(ds, ds_warnings->str, ds_warnings->length); } } - - if (!disable_info) - append_info(ds, affected_rows, mysql_info(mysql)); } if (res) @@ -6960,40 +7012,34 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command, } /* - Need to grab affected rows information before getting - warnings here + Fetch info before fetching warnings, since it will be reset + otherwise. */ - { - ulonglong UNINIT_VAR(affected_rows); - if (!disable_info) - affected_rows= mysql_affected_rows(mysql); + if (!disable_info) + append_info(ds, mysql_stmt_affected_rows(stmt), mysql_info(mysql)); - if (!disable_warnings) - { - /* Get the warnings from execute */ + if (!disable_warnings) + { + /* Get the warnings from execute */ - /* Append warnings to ds - if there are any */ - if (append_warnings(&ds_execute_warnings, mysql) || - ds_execute_warnings.length || - ds_prepare_warnings.length || - ds_warnings->length) - { - dynstr_append_mem(ds, "Warnings:\n", 10); - if (ds_warnings->length) - dynstr_append_mem(ds, ds_warnings->str, - ds_warnings->length); - if (ds_prepare_warnings.length) - dynstr_append_mem(ds, ds_prepare_warnings.str, - ds_prepare_warnings.length); - if (ds_execute_warnings.length) - dynstr_append_mem(ds, ds_execute_warnings.str, - ds_execute_warnings.length); - } + /* Append warnings to ds - if there are any */ + if (append_warnings(&ds_execute_warnings, mysql) || + ds_execute_warnings.length || + ds_prepare_warnings.length || + ds_warnings->length) + { + dynstr_append_mem(ds, "Warnings:\n", 10); + if (ds_warnings->length) + dynstr_append_mem(ds, ds_warnings->str, + ds_warnings->length); + if (ds_prepare_warnings.length) + dynstr_append_mem(ds, ds_prepare_warnings.str, + ds_prepare_warnings.length); + if (ds_execute_warnings.length) + dynstr_append_mem(ds, ds_execute_warnings.str, + ds_execute_warnings.length); } - - if (!disable_info) - append_info(ds, affected_rows, mysql_info(mysql)); } } @@ -7043,6 +7089,10 @@ int util_query(MYSQL* org_mysql, const char* query){ if (!(mysql= mysql_init(mysql))) die("Failed in mysql_init()"); + if (opt_connect_timeout) + mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, + (void *) &opt_connect_timeout); + /* enable local infile, in non-binary builds often disabled by default */ mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, 0); safe_connect(mysql, "util", org_mysql->host, org_mysql->user, @@ -7091,7 +7141,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) /* Evaluate query if this is an eval command */ - if (command->type == Q_EVAL) + if (command->type == Q_EVAL || command->type == Q_SEND_EVAL) { init_dynamic_string(&eval_query, "", command->query_len+256, 1024); do_eval(&eval_query, command->query, command->end, FALSE); @@ -7638,8 +7688,8 @@ int main(int argc, char **argv) my_init_dynamic_array(&q_lines, sizeof(struct st_command*), 1024, 1024); - if (hash_init(&var_hash, charset_info, - 1024, 0, 0, get_var_key, var_free, MYF(0))) + if (my_hash_init(&var_hash, charset_info, + 1024, 0, 0, get_var_key, var_free, MYF(0))) die("Variable hash initialization failed"); var_set_string("$MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION); @@ -7702,6 +7752,9 @@ int main(int argc, char **argv) st_connection *con= connections; if (!( mysql_init(&con->mysql))) die("Failed in mysql_init()"); + if (opt_connect_timeout) + mysql_options(&con->mysql, MYSQL_OPT_CONNECT_TIMEOUT, + (void *) &opt_connect_timeout); if (opt_compress) mysql_options(&con->mysql,MYSQL_OPT_COMPRESS,NullS); mysql_options(&con->mysql, MYSQL_OPT_LOCAL_INFILE, 0); @@ -7806,9 +7859,6 @@ int main(int argc, char **argv) case Q_DISCONNECT: case Q_DIRTY_CLOSE: do_close_connection(command); break; - case Q_RPL_PROBE: do_rpl_probe(command); break; - case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(command); break; - case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(command); break; case Q_ENABLE_QUERY_LOG: disable_query_log=0; break; case Q_DISABLE_QUERY_LOG: disable_query_log=1; break; case Q_ENABLE_ABORT_ON_ERROR: abort_on_error=1; break; @@ -7850,6 +7900,7 @@ int main(int argc, char **argv) case Q_MOVE_FILE: do_move_file(command); break; case Q_CHMOD_FILE: do_chmod_file(command); break; case Q_PERL: do_perl(command); break; + case Q_RESULT_FORMAT_VERSION: do_result_format_version(command); break; case Q_DELIMITER: do_delimiter(command); break; @@ -7915,6 +7966,7 @@ int main(int argc, char **argv) break; } case Q_SEND: + case Q_SEND_EVAL: if (!*command->first_argument) { /* @@ -7966,9 +8018,38 @@ int main(int argc, char **argv) do_sync_with_master2(command, 0); break; } - case Q_COMMENT: /* Ignore row */ + case Q_COMMENT: + { command->last_argument= command->end; + + /* Don't output comments in v1 */ + if (opt_result_format_version == 1) + break; + + /* Don't output comments if query logging is off */ + if (disable_query_log) + break; + + /* Write comment's with two starting #'s to result file */ + const char* p= command->query; + if (p && *p == '#' && *(p+1) == '#') + { + dynstr_append_mem(&ds_res, command->query, command->query_len); + dynstr_append(&ds_res, "\n"); + } break; + } + case Q_EMPTY_LINE: + /* Don't output newline in v1 */ + if (opt_result_format_version == 1) + break; + + /* Don't output newline if query logging is off */ + if (disable_query_log) + break; + + dynstr_append(&ds_res, "\n"); + break; case Q_PING: handle_command_error(command, mysql_ping(&cur_con->mysql)); break; @@ -8984,7 +9065,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count, free_sets(&sets); DBUG_RETURN(0); } - VOID(make_new_set(&sets)); /* Set starting set */ + (void) make_new_set(&sets); /* Set starting set */ make_sets_invisible(&sets); /* Hide previus sets */ used_sets=-1; word_states=make_new_set(&sets); /* Start of new word */ @@ -9455,7 +9536,7 @@ int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name) pa->flag[pa->typelib.count]=0; /* Reset flag */ pa->typelib.type_names[pa->typelib.count++]= (char*) pa->str+pa->length; pa->typelib.type_names[pa->typelib.count]= NullS; /* Put end-mark */ - VOID(strmov((char*) pa->str+pa->length,name)); + (void) strmov((char*) pa->str+pa->length,name); pa->length+=length; DBUG_RETURN(0); } /* insert_pointer_name */ diff --git a/client/readline.cc b/client/readline.cc index b32cb71b0de..73ce7c3b8c7 100644 --- a/client/readline.cc +++ b/client/readline.cc @@ -33,7 +33,7 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file) if (!(line_buff=(LINE_BUFFER*) my_malloc(sizeof(*line_buff),MYF(MY_WME | MY_ZEROFILL)))) return 0; - if (init_line_buffer(line_buff,fileno(file),IO_SIZE,max_size)) + if (init_line_buffer(line_buff,my_fileno(file),IO_SIZE,max_size)) { my_free(line_buff,MYF(0)); return 0; diff --git a/client/sql_string.cc b/client/sql_string.cc index dc6147b563f..3292bc7e6f2 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -23,6 +23,7 @@ #include <my_sys.h> #include <m_string.h> #include <m_ctype.h> +#include <mysql_com.h> #ifdef HAVE_FCONVERT #include <floatingpoint.h> #endif @@ -129,7 +130,7 @@ bool String::set(double num,uint decimals, CHARSET_INFO *cs) int decpt,sign; char *pos,*to; - VOID(fconvert(num,(int) decimals,&decpt,&sign,buff+1)); + (void) fconvert(num,(int) decimals,&decpt,&sign,buff+1); if (!my_isdigit(&my_charset_latin1, buff[1])) { // Nan or Inf pos=buff+1; diff --git a/client/sql_string.h b/client/sql_string.h index 0e6d6da4476..1a3ac5d33c5 100644 --- a/client/sql_string.h +++ b/client/sql_string.h @@ -22,10 +22,6 @@ #pragma interface /* gcc class implementation */ #endif -#ifndef NOT_FIXED_DEC -#define NOT_FIXED_DEC 31 -#endif - class String; int sortcmp(const String *a,const String *b, CHARSET_INFO *cs); String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); |