diff options
Diffstat (limited to 'client')
-rwxr-xr-x | client/CMakeLists.txt | 61 | ||||
-rw-r--r-- | client/Makefile.am | 7 | ||||
-rw-r--r-- | client/client_priv.h | 6 | ||||
-rw-r--r-- | client/mysql.cc | 77 | ||||
-rw-r--r-- | client/mysql_upgrade.c | 6 | ||||
-rw-r--r-- | client/mysqladmin.cc | 143 | ||||
-rw-r--r-- | client/mysqlbinlog.cc | 154 | ||||
-rw-r--r-- | client/mysqlcheck.c | 33 | ||||
-rw-r--r-- | client/mysqldump.c | 18 | ||||
-rw-r--r-- | client/mysqlimport.c | 3 | ||||
-rw-r--r-- | client/mysqlshow.c | 3 | ||||
-rw-r--r-- | client/mysqlslap.c | 3 | ||||
-rw-r--r-- | client/mysqltest.cc | 139 | ||||
-rw-r--r-- | client/sql_string.cc | 9 | ||||
-rw-r--r-- | client/sql_string.h | 5 |
15 files changed, 546 insertions, 121 deletions
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index c04b4fc4b59..5780da71bef 100755 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -15,7 +15,7 @@ # 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 +# We use the "mysqlclient" 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. @@ -26,61 +26,48 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/libmysql ${CMAKE_SOURCE_DIR}/regex ${CMAKE_SOURCE_DIR}/sql - ${CMAKE_SOURCE_DIR}/strings) + ${CMAKE_SOURCE_DIR}/strings + ${CMAKE_CURRENT_BINARY_DIR}) -ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c) -TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32) +MYSQL_ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c DESTINATION bin) +TARGET_LINK_LIBRARIES(mysql mysqlclient wsock32) -ADD_EXECUTABLE(mysqltest mysqltest.cc) +MYSQL_ADD_EXECUTABLE(mysqltest mysqltest.cc DESTINATION bin) SET_SOURCE_FILES_PROPERTIES(mysqltest.cc PROPERTIES COMPILE_FLAGS "-DTHREADS") TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys regex wsock32 dbug) -ADD_EXECUTABLE(mysqlcheck mysqlcheck.c) -TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient_notls wsock32) +MYSQL_ADD_EXECUTABLE(mysqlcheck mysqlcheck.c DESTINATION bin) +TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient wsock32) -ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c ../mysys/mf_getdate.c) -TARGET_LINK_LIBRARIES(mysqldump mysqlclient_notls wsock32) +MYSQL_ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c ../mysys/mf_getdate.c DESTINATION bin) +TARGET_LINK_LIBRARIES(mysqldump mysqlclient wsock32) -ADD_EXECUTABLE(mysqlimport mysqlimport.c) -TARGET_LINK_LIBRARIES(mysqlimport mysqlclient_notls wsock32) +MYSQL_ADD_EXECUTABLE(mysqlimport mysqlimport.c DESTINATION bin) +TARGET_LINK_LIBRARIES(mysqlimport mysqlclient wsock32) -ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c ../mysys/my_getpagesize.c) -TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient_notls wsock32) +MYSQL_ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c DESTINATION bin) +TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient wsock32) ADD_DEPENDENCIES(mysql_upgrade GenFixPrivs) -ADD_EXECUTABLE(mysqlshow mysqlshow.c) -TARGET_LINK_LIBRARIES(mysqlshow mysqlclient_notls wsock32) +MYSQL_ADD_EXECUTABLE(mysqlshow mysqlshow.c DESTINATION bin) +TARGET_LINK_LIBRARIES(mysqlshow mysqlclient wsock32) -ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc +MYSQL_ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc ../mysys/mf_tempdir.c ../mysys/my_new.cc ../mysys/my_bit.c ../mysys/my_bitmap.c ../mysys/my_vle.c - ../mysys/base64.c) -TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient_notls wsock32) + ../mysys/base64.c + DESTINATION bin) +TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient wsock32) -ADD_EXECUTABLE(mysqladmin mysqladmin.cc) -TARGET_LINK_LIBRARIES(mysqladmin mysqlclient_notls wsock32) +MYSQL_ADD_EXECUTABLE(mysqladmin mysqladmin.cc DESTINATION bin) +TARGET_LINK_LIBRARIES(mysqladmin mysqlclient wsock32) -ADD_EXECUTABLE(mysqlslap mysqlslap.c) +MYSQL_ADD_EXECUTABLE(mysqlslap mysqlslap.c DESTINATION bin) SET_SOURCE_FILES_PROPERTIES(mysqlslap.c PROPERTIES COMPILE_FLAGS "-DTHREADS") TARGET_LINK_LIBRARIES(mysqlslap mysqlclient mysys zlib wsock32 dbug) -ADD_EXECUTABLE(echo echo.c) -IF(EMBED_MANIFESTS) - MYSQL_EMBED_MANIFEST("mysql" "asInvoker") - MYSQL_EMBED_MANIFEST("mysqltest" "asInvoker") - MYSQL_EMBED_MANIFEST("mysqlcheck" "asInvoker") - MYSQL_EMBED_MANIFEST("mysqldump" "asInvoker") - MYSQL_EMBED_MANIFEST("mysqlimport" "asInvoker") - MYSQL_EMBED_MANIFEST("mysql_upgrade" "asInvoker") - MYSQL_EMBED_MANIFEST("mysqlshow" "asInvoker") - MYSQL_EMBED_MANIFEST("mysqlbinlog" "asInvoker") - MYSQL_EMBED_MANIFEST("mysqladmin" "asInvoker") - MYSQL_EMBED_MANIFEST("echo" "asInvoker") -ENDIF(EMBED_MANIFESTS) - -INSTALL(TARGETS mysql mysqltest mysqlcheck mysqldump mysqlimport mysql_upgrade mysqlshow - mysqlbinlog mysqladmin mysqlslap echo DESTINATION bin COMPONENT runtime) +MYSQL_ADD_EXECUTABLE(echo echo.c COMPONENT Test) diff --git a/client/Makefile.am b/client/Makefile.am index a7104093e5f..72540de0fe8 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -97,14 +97,15 @@ mysql_upgrade_SOURCES= mysql_upgrade.c \ # Fix for mit-threads DEFS = -DMYSQL_CLIENT_NO_THREADS \ - -DDEFAULT_MYSQL_HOME="\"$(prefix)\"" \ - -DMYSQL_DATADIR="\"$(localstatedir)\"" + -DDEFAULT_MYSQL_HOME='"$(prefix)"' \ + -DMYSQL_DATADIR='"$(localstatedir)"' sql_src=log_event.h mysql_priv.h rpl_constants.h \ rpl_utility.h rpl_tblmap.h rpl_tblmap.cc \ log_event.cc my_decimal.h my_decimal.cc \ log_event_old.h log_event_old.cc \ - rpl_record_old.h rpl_record_old.cc + rpl_record_old.h rpl_record_old.cc \ + sql_list.h rpl_filter.h sql_list.cc rpl_filter.cc strings_src=decimal.c strings_def.h link_sources: diff --git a/client/client_priv.h b/client/client_priv.h index 773d65c5d1e..9ad627f0832 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -62,6 +62,7 @@ enum options_client OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_SERVER_ARG, OPT_POSITION, OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME, OPT_SIGINT_IGNORE, OPT_HEXBLOB, OPT_ORDER_BY_PRIMARY, OPT_COUNT, + OPT_FLUSH_TABLES, #ifdef HAVE_NDBCLUSTER_DB OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, #endif @@ -95,5 +96,8 @@ enum options_client OPT_ABORT_SOURCE_ON_ERROR, OPT_FIRST_SLAVE, OPT_ALL, - OPT_MAX_CLIENT_OPTION + OPT_REWRITE_DB, + OPT_PLUGIN_DIR, + OPT_DEFAULT_PLUGIN, + OPT_MAX_CLIENT_OPTION /* should be always the last */ }; diff --git a/client/mysql.cc b/client/mysql.cc index 4d761945068..0ce28fa90c6 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -151,7 +151,7 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0, tty_password= 0, opt_nobeep=0, opt_reconnect=1, default_charset_used= 0, opt_secure_auth= 0, default_pager_set= 0, opt_sigint_ignore= 0, - show_warnings= 0, executing_query= 0, interrupted_query= 0, + show_warnings= 0, executing_query= 0, ignore_spaces= 0; static my_bool debug_info_flag, debug_check_flag, batch_abort_on_error; static my_bool column_types_flag; @@ -162,6 +162,7 @@ static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0; static uint my_end_arg; static char * opt_mysql_unix_port=0; static int connect_flag=CLIENT_INTERACTIVE; +static int interrupted_query= 0; 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; @@ -174,6 +175,7 @@ static int wait_time = 5; static STATUS status; static ulong select_limit,max_join_size,opt_connect_timeout=0; static char mysql_charsets_dir[FN_REFLEN+1]; +static char *opt_plugin_dir= 0, *opt_default_auth; static const char *xmlmeta[] = { "&", "&", "<", "<", @@ -1028,7 +1030,8 @@ static COMMANDS commands[] = { { (char *)NULL, 0, 0, 0, ""} }; -static const char *load_default_groups[]= { "mysql","client",0 }; +static const char *load_default_groups[]= +{ "mysql", "client", "client-server", "client-mariadb", 0 }; static int embedded_server_arg_count= 0; static char *embedded_server_args[MAX_SERVER_ARGS]; @@ -1576,6 +1579,13 @@ static struct my_option my_long_options[] = {"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.", &show_warnings, &show_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", + (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"default_auth", OPT_PLUGIN_DIR, + "Default authentication client-side plugin to use.", + (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -3622,7 +3632,7 @@ static void print_warnings() mysql_store_result_for_lazy(&result); /* Bail out when no warnings */ - if (!(num_rows= mysql_num_rows(result))) + if (!result || !(num_rows= mysql_num_rows(result))) goto end; cur= mysql_fetch_row(result); @@ -3987,7 +3997,7 @@ static int com_connect(String *buffer, char *line) { char *tmp, buff[256]; - bool save_rehash= opt_rehash; + my_bool save_rehash= opt_rehash; int error; bzero(buff, sizeof(buff)); @@ -4286,6 +4296,58 @@ char *get_arg(char *line, my_bool get_next_arg) } +/** + An example of mysql_authentication_dialog_ask callback. + + The C function with the name "mysql_authentication_dialog_ask", if exists, + will be used by the "dialog" client authentication plugin when user + input is needed. This function should be of mysql_authentication_dialog_ask_t + type. If the function does not exists, a built-in implementation will be + used. + + @param mysql mysql + @param type type of the input + 1 - normal string input + 2 - password string + @param prompt prompt + @param buf a buffer to store the use input + @param buf_len the length of the buffer + + @retval a pointer to the user input string. + It may be equal to 'buf' or to 'mysql->password'. + In all other cases it is assumed to be an allocated + string, and the "dialog" plugin will free() it. +*/ + +MYSQL_PLUGIN_EXPORT +char *mysql_authentication_dialog_ask(MYSQL *mysql, int type, + const char *prompt, + char *buf, int buf_len) +{ + char *s=buf; + + fputs("[mariadb] ", stdout); + fputs(prompt, stdout); + fputs(" ", stdout); + + if (type == 2) /* password */ + { + s= get_tty_password(""); + strnmov(buf, s, buf_len); + buf[buf_len-1]= 0; + my_free(s, MYF(0)); + } + else + { + if (!fgets(buf, buf_len-1, stdin)) + buf[0]= 0; + else if (buf[0] && (s= strend(buf))[-1] == '\n') + s[-1]= 0; + } + + return buf; +} + static int sql_real_connect(char *host,char *database,char *user,char *password, uint silent) @@ -4331,6 +4393,13 @@ sql_real_connect(char *host,char *database,char *user,char *password, } if (default_charset_used) mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset); + + if (opt_plugin_dir && *opt_plugin_dir) + mysql_options(&mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir); + + if (opt_default_auth && *opt_default_auth) + mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth); + if (!mysql_real_connect(&mysql, host, user, password, database, opt_mysql_port, opt_mysql_unix_port, connect_flag | CLIENT_MULTI_STATEMENTS)) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 90a5ed6dad0..c6e54cba67b 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -819,8 +819,10 @@ static int run_sql_fix_privilege_tables(void) static const char *load_default_groups[]= { - "client", /* Read settings how to connect to server */ - "mysql_upgrade", /* Read special settings for mysql_upgrade*/ + "client", /* Read settings how to connect to server */ + "mysql_upgrade", /* Read special settings for mysql_upgrade */ + "client-server", /* Reads settings common between client & server */ + "client-mariadb", /* Read mariadb unique client settings */ 0 }; diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 22a58e31f2c..0716e391ab4 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -26,7 +26,7 @@ #include <mysql.h> #include <sql_common.h> -#define ADMIN_VERSION "8.42" +#define ADMIN_VERSION "9.0" #define MAX_MYSQL_VAR 512 #define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */ #define MAX_TRUNC_LENGTH 3 @@ -99,7 +99,10 @@ enum commands { ADMIN_FLUSH_HOSTS, ADMIN_FLUSH_TABLES, ADMIN_PASSWORD, ADMIN_PING, ADMIN_EXTENDED_STATUS, ADMIN_FLUSH_STATUS, ADMIN_FLUSH_PRIVILEGES, ADMIN_START_SLAVE, ADMIN_STOP_SLAVE, - ADMIN_FLUSH_THREADS, ADMIN_OLD_PASSWORD + ADMIN_FLUSH_THREADS, ADMIN_OLD_PASSWORD, ADMIN_FLUSH_SLOW_LOG, + ADMIN_FLUSH_TABLE_STATISTICS, ADMIN_FLUSH_INDEX_STATISTICS, + ADMIN_FLUSH_USER_STATISTICS, ADMIN_FLUSH_CLIENT_STATISTICS, + ADMIN_FLUSH_ALL_STATUS, ADMIN_FLUSH_ALL_STATISTICS }; static const char *command_names[]= { "create", "drop", "shutdown", @@ -109,7 +112,10 @@ static const char *command_names[]= { "flush-hosts", "flush-tables", "password", "ping", "extended-status", "flush-status", "flush-privileges", "start-slave", "stop-slave", - "flush-threads","old-password", + "flush-threads", "old-password", "flush-slow-log", + "flush-table-statistics", "flush-index-statistics", + "flush-user-statistics", "flush-client-statistics", + "flush-all-status", "flush-all-statistics", NullS }; @@ -219,7 +225,8 @@ static struct my_option my_long_options[] = }; -static const char *load_default_groups[]= { "mysqladmin","client",0 }; +static const char *load_default_groups[]= +{ "mysqladmin", "client", "client-server", "client-mariadb", 0 }; my_bool get_one_option(int optid, const struct my_option *opt __attribute__((unused)), @@ -597,7 +604,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) for (; argc > 0 ; argv++,argc--) { - switch (find_type(argv[0],&command_typelib,2)) { + int command; + switch ((command= find_type(argv[0],&command_typelib,2))) { case ADMIN_CREATE: { char buff[FN_REFLEN+20]; @@ -674,7 +682,11 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) if (mysql_refresh(mysql, (uint) ~(REFRESH_GRANT | REFRESH_STATUS | REFRESH_READ_LOCK | REFRESH_SLAVE | - REFRESH_MASTER))) + REFRESH_MASTER | REFRESH_TABLE_STATS | + REFRESH_INDEX_STATS | + REFRESH_USER_STATS | + REFRESH_SLOW_QUERY_LOG | + REFRESH_CLIENT_STATS))) { my_printf_error(0, "refresh failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -692,7 +704,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) case ADMIN_VER: new_line=1; print_version(); - puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); + puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc,\n" + "2009 Monty Program Ab"); puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); printf("Server version\t\t%s\n", mysql_get_server_info(mysql)); printf("Protocol version\t%d\n", mysql_get_proto_info(mysql)); @@ -868,9 +881,19 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_LOGS: { - if (mysql_refresh(mysql,REFRESH_LOG)) + if (mysql_query(mysql,"flush logs")) { - my_printf_error(0, "refresh failed; error: '%s'", error_flags, + my_printf_error(0, "flush failed; error: '%s'", error_flags, + mysql_error(mysql)); + return -1; + } + break; + } + case ADMIN_FLUSH_SLOW_LOG: + { + if (mysql_query(mysql,"flush slow query logs")) + { + my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -880,7 +903,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { if (mysql_query(mysql,"flush hosts")) { - my_printf_error(0, "refresh failed; error: '%s'", error_flags, + my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -890,7 +913,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { if (mysql_query(mysql,"flush tables")) { - my_printf_error(0, "refresh failed; error: '%s'", error_flags, + my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -900,7 +923,71 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { if (mysql_query(mysql,"flush status")) { - my_printf_error(0, "refresh failed; error: '%s'", error_flags, + my_printf_error(0, "flush failed; error: '%s'", error_flags, + mysql_error(mysql)); + return -1; + } + break; + } + case ADMIN_FLUSH_TABLE_STATISTICS: + { + if (mysql_query(mysql,"flush table_statistics")) + { + my_printf_error(0, "flush failed; error: '%s'", error_flags, + mysql_error(mysql)); + return -1; + } + break; + } + case ADMIN_FLUSH_INDEX_STATISTICS: + { + if (mysql_query(mysql,"flush index_statistics")) + { + my_printf_error(0, "flush failed; error: '%s'", error_flags, + mysql_error(mysql)); + return -1; + } + break; + } + case ADMIN_FLUSH_USER_STATISTICS: + { + if (mysql_query(mysql,"flush user_statistics")) + { + my_printf_error(0, "flush failed; error: '%s'", error_flags, + mysql_error(mysql)); + return -1; + } + break; + } + case ADMIN_FLUSH_CLIENT_STATISTICS: + { + if (mysql_query(mysql,"flush client_statistics")) + { + my_printf_error(0, "flush failed; error: '%s'", error_flags, + mysql_error(mysql)); + return -1; + } + break; + } + case ADMIN_FLUSH_ALL_STATISTICS: + { + if (mysql_query(mysql, + "flush table_statistics,index_statistics," + "user_statistics,client_statistics")) + { + my_printf_error(0, "flush failed; error: '%s'", error_flags, + mysql_error(mysql)); + return -1; + } + break; + } + case ADMIN_FLUSH_ALL_STATUS: + { + if (mysql_query(mysql, + "flush status,table_statistics,index_statistics," + "user_statistics,client_statistics")) + { + my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); return -1; } @@ -1072,7 +1159,8 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); + puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc,\n" + "2009 Monty Program Ab"); puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); puts("Administration program for the mysqld daemon."); printf("Usage: %s [OPTIONS] command command....\n", my_progname); @@ -1080,16 +1168,23 @@ static void usage(void) my_print_variables(my_long_options); print_defaults("my",load_default_groups); puts("\nWhere command is a one or more of: (Commands may be shortened)\n\ - create databasename Create a new database\n\ - debug Instruct server to write debug information to log\n\ - drop databasename Delete a database and all its tables\n\ - extended-status Gives an extended status message from the server\n\ - flush-hosts Flush all cached hosts\n\ - flush-logs Flush all logs\n\ - flush-status Clear status variables\n\ - flush-tables Flush all tables\n\ - flush-threads Flush the thread cache\n\ - flush-privileges Reload grant tables (same as reload)\n\ + create databasename Create a new database\n\ + debug Instruct server to write debug information to log\n\ + drop databasename Delete a database and all its tables\n\ + extended-status Gives an extended status message from the server\n\ + flush-all-statistics Flush all statistics tables\n\ + flush-all-status Flush status and statistics\n\ + flush-client-statistics Flush client statistics\n\ + flush-hosts Flush all cached hosts\n\ + flush-index-statistics Flush index statistics\n\ + flush-logs Flush all logs\n\ + flush-privileges Reload grant tables (same as reload)\n\ + flush-slow-log Flush slow query log\n\ + flush-status Clear status variables\n\ + flush-table-statistics Clear table statistics\n\ + flush-tables Flush all tables\n\ + flush-threads Flush the thread cache\n\ + flush-user-statistics Flush user statistics\n\ kill id,id,... Kill mysql threads"); #if MYSQL_VERSION_ID >= 32200 puts("\ @@ -1380,7 +1475,7 @@ static my_bool wait_pidfile(char *pidfile, time_t last_modified, struct stat *pidfile_status) { char buff[FN_REFLEN]; - int error= 1; + my_bool error= 1; uint count= 0; DBUG_ENTER("wait_pidfile"); diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 6ec67766a94..b831fcc2a0c 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -37,6 +37,15 @@ #include "log_event.h" #include "sql_common.h" +/* Needed for Rpl_filter */ +CHARSET_INFO* system_charset_info= &my_charset_utf8_general_ci; + +#include "sql_string.h" // needed for Rpl_filter +#include "sql_list.h" // needed for Rpl_filter +#include "rpl_filter.h" + +Rpl_filter *binlog_filter; + #define BIN_LOG_HEADER_SIZE 4 #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) @@ -58,7 +67,8 @@ static FILE *result_file; #ifndef DBUG_OFF static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace"; #endif -static const char *load_default_groups[]= { "mysqlbinlog","client",0 }; +static const char *load_default_groups[]= +{ "mysqlbinlog", "client", "client-server", "client-mariadb", 0 }; static void error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); static void warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); @@ -622,6 +632,47 @@ static bool shall_skip_database(const char *log_dbname) /** + Print "use <db>" statement when current db is to be changed. + + We have to control emiting USE statements according to rewrite-db options. + We have to do it here (see process_event() below) and to suppress + producing USE statements by corresponding log event print-functions. +*/ + +static void +print_use_stmt(PRINT_EVENT_INFO* pinfo, const Query_log_event *ev) +{ + const char* db= ev->db; + const size_t db_len= ev->db_len; + + // pinfo->db is the current db. + // If current db is the same as required db, do nothing. + if ((ev->flags & LOG_EVENT_SUPPRESS_USE_F) || !db || + !memcmp(pinfo->db, db, db_len + 1)) + return; + + // Current db and required db are different. + // Check for rewrite rule for required db. (Note that in a rewrite rule + // neither db_from nor db_to part can be empty). + size_t len_to= 0; + const char *db_to= binlog_filter->get_rewrite_db(db, &len_to); + + // If there is no rewrite rule for db (in this case len_to is left = 0), + // printing of the corresponding USE statement is left for log event + // print-function. + if (!len_to) + return; + + // In case of rewrite rule print USE statement for db_to + fprintf(result_file, "use %s%s\n", db_to, pinfo->delimiter); + + // Copy the *original* db to pinfo to suppress emiting + // of USE stmts by log_event print-functions. + memcpy(pinfo->db, db, db_len + 1); +} + + +/** Prints the given event in base64 format. The header is printed to the head cache and the body is printed to @@ -741,9 +792,11 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, switch (ev_type) { case QUERY_EVENT: - if (!((Query_log_event*)ev)->is_trans_keyword() && - shall_skip_database(((Query_log_event*)ev)->db)) + { + Query_log_event *qe= (Query_log_event*)ev; + if (!qe->is_trans_keyword() && shall_skip_database(qe->db)) goto end; + print_use_stmt(print_event_info, qe); if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) { if ((retval= write_event_header_and_base64(ev, result_file, @@ -756,6 +809,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, if (head->error == -1) goto err; break; + } case CREATE_FILE_EVENT: { @@ -890,6 +944,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, if (!shall_skip_database(exlq->db)) { + print_use_stmt(print_event_info, exlq); if (fname) { convert_path_to_forward_slashes(fname); @@ -919,6 +974,13 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, destroy_evt= FALSE; goto end; } + size_t len_to= 0; + const char* db_to= binlog_filter->get_rewrite_db(map->get_db_name(), &len_to); + if (len_to && map->rewrite_db(db_to, len_to, glob_description_event)) + { + error("Could not rewrite database name"); + goto err; + } } case WRITE_ROWS_EVENT: case DELETE_ROWS_EVENT: @@ -1006,14 +1068,16 @@ err: retval= ERROR_STOP; end: rec_count++; + /* - Destroy the log_event object. If reading from a remote host, - set the temp_buf to NULL so that memory isn't freed twice. + Destroy the log_event object. + MariaDB MWL#36: mainline does this: + If reading from a remote host, + set the temp_buf to NULL so that memory isn't freed twice. + We no longer do that, we use Rpl_filter::event_owns_temp_buf instead. */ if (ev) { - if (remote_opt) - ev->temp_buf= 0; if (destroy_evt) /* destroy it later if not set (ignored table map) */ delete ev; } @@ -1179,6 +1243,10 @@ that may lead to an endless loop.", "Used to reserve file descriptors for use by this program.", &open_files_limit, &open_files_limit, 0, GET_ULONG, REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0}, + {"rewrite-db", OPT_REWRITE_DB, + "Updates to a database with a different name than the original. \ +Example: rewrite-db='from->to'.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -1373,6 +1441,53 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), (find_type_or_exit(argument, &base64_output_mode_typelib, opt->name)-1); } break; + case OPT_REWRITE_DB: // db_from->db_to + { + /* See also handling of OPT_REPLICATE_REWRITE_DB in sql/mysqld.cc */ + char* ptr; + char* key= argument; // db-from + char* val; // db-to + + // Where key begins + while (*key && my_isspace(&my_charset_latin1, *key)) + key++; + + // Where val begins + if (!(ptr= strstr(argument, "->"))) + { + sql_print_error("Bad syntax in rewrite-db: missing '->'!\n"); + return 1; + } + val= ptr + 2; + while (*val && my_isspace(&my_charset_latin1, *val)) + val++; + + // Write \0 and skip blanks at the end of key + *ptr-- = 0; + while (my_isspace(&my_charset_latin1, *ptr) && ptr > argument) + *ptr-- = 0; + + if (!*key) + { + sql_print_error("Bad syntax in rewrite-db: empty db-from!\n"); + return 1; + } + + // Skip blanks at the end of val + ptr= val; + while (*ptr && !my_isspace(&my_charset_latin1, *ptr)) + ptr++; + *ptr= 0; + + if (!*val) + { + sql_print_error("Bad syntax in rewrite-db: empty db-to!\n"); + return 1; + } + + binlog_filter->add_db_rewrite(key, val); + break; + } case 'v': if (argument == disabled_my_option) verbose= 0; @@ -1417,7 +1532,7 @@ static int parse_args(int *argc, char*** argv) */ static Exit_status safe_connect() { - /* Close and old connections to MySQL */ + /* Close any old connections to MySQL */ if (mysql) mysql_close(mysql); @@ -1646,7 +1761,7 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, If reading from a remote host, ensure the temp_buf for the Log_event class is pointing to the incoming stream. */ - ev->register_temp_buf((char *) net->read_pos + 1); + ev->register_temp_buf((char *) net->read_pos + 1, FALSE); Log_event_type type= ev->get_type_code(); if (glob_description_event->binlog_version >= 3 || @@ -2052,6 +2167,8 @@ end: return retval; } +/* Used in sql_alloc(). Inited and freed in main() */ +MEM_ROOT s_mem_root; int main(int argc, char** argv) { @@ -2064,8 +2181,16 @@ int main(int argc, char** argv) my_init_time(); // for time functions + init_alloc_root(&s_mem_root, 16384, 0); + if (!(binlog_filter= new Rpl_filter)) + { + error("Failed to create Rpl_filter"); + exit(1); + } + if (load_defaults("my", load_default_groups, &argc, &argv)) exit(1); + defaults_argv= argv; parse_args(&argc, (char***)&argv); @@ -2152,6 +2277,8 @@ int main(int argc, char** argv) if (result_file != stdout) my_fclose(result_file, MYF(0)); cleanup(); + delete binlog_filter; + free_root(&s_mem_root, MYF(0)); free_defaults(defaults_argv); my_free_open_file_info(); load_processor.destroy(); @@ -2163,6 +2290,12 @@ int main(int argc, char** argv) DBUG_RETURN(retval == ERROR_STOP ? 1 : 0); } + +void *sql_alloc(size_t size) +{ + return alloc_root(&s_mem_root, size); +} + /* We must include this here as it's compiled with different options for the server @@ -2173,4 +2306,7 @@ int main(int argc, char** argv) #include "my_decimal.cc" #include "log_event.cc" #include "log_event_old.cc" +#include "sql_string.cc" +#include "sql_list.cc" +#include "rpl_filter.cc" diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index d45dccf328d..8bf6cbe8d83 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -16,7 +16,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#define CHECK_VERSION "2.6.0" +#define CHECK_VERSION "2.7.0" #include "client_priv.h" #include <m_ctype.h> @@ -35,8 +35,8 @@ static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0, opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0, opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0, tty_password= 0, opt_frm= 0, debug_info_flag= 0, debug_check_flag= 0, - opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0, - opt_write_binlog= 1; + opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0; +static my_bool opt_write_binlog= 1, opt_flush_tables= 0; static uint verbose = 0, opt_mysql_port=0; static int my_end_arg; static char * opt_mysql_unix_port = 0; @@ -121,6 +121,9 @@ static struct my_option my_long_options[] = "If you are using this option with CHECK TABLE, it will ensure that the table is 100 percent consistent, but will take a long time. If you are using this option with REPAIR TABLE, it will force using old slow repair with keycache method, instead of much faster repair by sorting.", &opt_extended, &opt_extended, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"flush", OPT_FLUSH_TABLES, "Flush each table after check. This is useful if you don't want to have the checked tables take up space in the caches after the check", + &opt_flush_tables, &opt_flush_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0 }, {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host",'h', "Connect to host.", ¤t_host, @@ -187,7 +190,8 @@ static struct my_option my_long_options[] = {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; -static const char *load_default_groups[] = { "mysqlcheck", "client", 0 }; +static const char *load_default_groups[]= +{ "mysqlcheck", "client", "client-server", "client-mariadb", 0 }; static void print_version(void); @@ -684,6 +688,7 @@ static int disable_binlog() static int handle_request_for_tables(char *tables, uint length) { char *query, *end, options[100], message[100]; + char table_name_buff[NAME_CHAR_LEN*2*2+1], *table_name; uint query_length= 0; const char *op = 0; @@ -722,13 +727,17 @@ static int handle_request_for_tables(char *tables, uint length) /* No backticks here as we added them before */ query_length= my_sprintf(query, (query, "%s TABLE %s %s", op, tables, options)); + table_name= tables; } else { - char *ptr; + char *ptr, *org; - ptr= strmov(strmov(query, op), " TABLE "); + org= ptr= strmov(strmov(query, op), " TABLE "); ptr= fix_table_name(ptr, tables); + strmake(table_name_buff, org, min((int) sizeof(table_name_buff)-1, + (int) (ptr - org))); + table_name= table_name_buff; ptr= strxmov(ptr, " ", options, NullS); query_length= (uint) (ptr - query); } @@ -736,9 +745,21 @@ static int handle_request_for_tables(char *tables, uint length) { sprintf(message, "when executing '%s TABLE ... %s'", op, options); DBerror(sock, message); + my_free(query, MYF(0)); return 1; } print_result(); + if (opt_flush_tables) + { + query_length= my_sprintf(query, + (query, "FLUSH TABLES %s", table_name)); + if (mysql_real_query(sock, query, query_length)) + { + DBerror(sock, query); + my_free(query, MYF(0)); + return 1; + } + } my_free(query, MYF(0)); return 0; } diff --git a/client/mysqldump.c b/client/mysqldump.c index 38c0fb0d0bc..ffb5e076417 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -38,7 +38,7 @@ ** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov */ -#define DUMP_VERSION "10.13" +#define DUMP_VERSION "10.14" #include <my_global.h> #include <my_sys.h> @@ -494,7 +494,8 @@ static struct my_option my_long_options[] = {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; -static const char *load_default_groups[]= { "mysqldump","client",0 }; +static const char *load_default_groups[]= +{ "mysqldump", "client", "client-server", "client-mariadb", 0 }; static void maybe_exit(int error); static void die(int error, const char* reason, ...); @@ -647,8 +648,13 @@ static void write_header(FILE *sql_file, char *db_name) if (!path) { + if (!opt_no_create_info) + { + /* We don't need unique checks as the table is created just before */ + fprintf(md_result_file,"\ +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\n"); + } fprintf(md_result_file,"\ -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\n\ /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;\n\ "); } @@ -678,8 +684,12 @@ static void write_footer(FILE *sql_file) if (!path) { fprintf(md_result_file,"\ -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;\n\ +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;\n"); + if (!opt_no_create_info) + { + fprintf(md_result_file,"\ /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;\n"); + } } if (opt_set_charset) fprintf(sql_file, diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 8a71a07e471..654f19f6f57 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -185,7 +185,8 @@ static struct my_option my_long_options[] = }; -static const char *load_default_groups[]= { "mysqlimport","client",0 }; +static const char *load_default_groups[]= +{ "mysqlimport","client", "client-server", "client-mariadb", 0 }; #include <help_start.h> diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 955cfe4442a..e1cbfcb9404 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -55,7 +55,8 @@ static void print_res_header(MYSQL_RES *result); static void print_res_top(MYSQL_RES *result); static void print_res_row(MYSQL_RES *result,MYSQL_ROW cur); -static const char *load_default_groups[]= { "mysqlshow","client",0 }; +static const char *load_default_groups[]= +{ "mysqlshow","client", "client-server", "client-mariadb", 0 }; static char * opt_mysql_unix_port=0; int main(int argc, char **argv) diff --git a/client/mysqlslap.c b/client/mysqlslap.c index d4a6766bfdc..7cac3a14379 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -180,7 +180,8 @@ static uint opt_protocol= 0; static int get_options(int *argc,char ***argv); static uint opt_mysql_port= 0; -static const char *load_default_groups[]= { "mysqlslap","client",0 }; +static const char *load_default_groups[]= +{ "mysqlslap", "client", "client-server", "client-mariadb", 0 }; typedef struct statement statement; diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 7720a128270..86deb2eadac 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -39,6 +39,7 @@ #include "client_priv.h" #include <mysql_version.h> #include <mysqld_error.h> +#include <sql_common.h> #include <m_ctype.h> #include <my_dir.h> #include <hash.h> @@ -116,11 +117,13 @@ static my_bool disable_connect_log= 1; static my_bool disable_warnings= 0; static my_bool prepare_warnings_enabled= 0; static my_bool disable_info= 1; +static char *opt_plugin_dir= 0, *opt_default_auth; static my_bool abort_on_error= 1; static my_bool server_initialized= 0; static my_bool is_windows= 0; static char **default_argv; -static const char *load_default_groups[]= { "mysqltest", "client", 0 }; +static const char *load_default_groups[]= +{ "mysqltest", "client", "client-server", "client-mariadb", 0 }; static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer; static uint start_lineno= 0; /* Start line of current command */ @@ -602,6 +605,10 @@ public: DBUG_VOID_RETURN; DBUG_ASSERT(ds->str); +#ifdef EXTRA_DEBUG + DBUG_PRINT("QQ", ("str: %*s", (int) ds->length, ds->str)); +#endif + if (fwrite(ds->str, 1, ds->length, m_file) != ds->length) die("Failed to write %lu bytes to '%s', errno: %d", (unsigned long)ds->length, m_file_name, errno); @@ -732,6 +739,9 @@ void handle_error(struct st_command*, const char *err_sqlstate, DYNAMIC_STRING *ds); void handle_no_error(struct st_command*); +static void handle_no_active_connection(struct st_command* command, + struct st_connection *cn, DYNAMIC_STRING *ds); + #ifdef EMBEDDED_LIBRARY /* workaround for MySQL BUG#57491 */ @@ -1308,6 +1318,7 @@ void die(const char *fmt, ...) DBUG_ENTER("die"); DBUG_PRINT("enter", ("start_lineno: %d", start_lineno)); + fflush(stdout); /* Print the error message */ fprintf(stderr, "mysqltest: "); if (cur_file && cur_file != file_stack) @@ -1394,6 +1405,7 @@ void verbose_msg(const char *fmt, ...) if (!verbose) DBUG_VOID_RETURN; + fflush(stdout); va_start(args, fmt); fprintf(stderr, "mysqltest: "); if (cur_file && cur_file != file_stack) @@ -1404,6 +1416,7 @@ void verbose_msg(const char *fmt, ...) vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); va_end(args); + fflush(stderr); DBUG_VOID_RETURN; } @@ -1488,6 +1501,8 @@ static int run_command(char* cmd, char buf[512]= {0}; FILE *res_file; int error; + DBUG_ENTER("run_command"); + DBUG_PRINT("enter", ("cmd: %s", cmd)); if (!(res_file= popen(cmd, "r"))) die("popen(\"%s\", \"r\") failed", cmd); @@ -1508,7 +1523,7 @@ static int run_command(char* cmd, } error= pclose(res_file); - return WEXITSTATUS(error); + DBUG_RETURN(WEXITSTATUS(error)); } @@ -2275,6 +2290,19 @@ void var_query_set(VAR *var, const char *query, const char** query_end) DBUG_ENTER("var_query_set"); LINT_INIT(res); + if (!mysql) + { + struct st_command command; + memset(&command, 0, sizeof(command)); + command.query= (char*)query; + command.first_word_len= (*query_end - query); + command.first_argument= command.query + command.first_word_len; + command.end= (char*)*query_end; + command.abort_on_error= 1; /* avoid uninitialized variables */ + handle_no_active_connection(&command, cur_con, &ds_res); + DBUG_VOID_RETURN; + } + /* Only white space or ) allowed past ending ` */ while (end > query && *end != '`') { @@ -2380,6 +2408,12 @@ void var_set_query_get_value(struct st_command *command, VAR *var) DBUG_ENTER("var_set_query_get_value"); LINT_INIT(res); + if (!mysql) + { + handle_no_active_connection(command, cur_con, &ds_res); + DBUG_VOID_RETURN; + } + strip_parentheses(command); DBUG_PRINT("info", ("query: %s", command->query)); check_command_args(command, command->first_argument, query_get_value_args, @@ -2538,6 +2572,7 @@ void eval_expr(VAR *v, const char *p, const char **p_end, bool do_eval) command.first_word_len= len; command.first_argument= command.query + len; command.end= (char*)*p_end; + command.abort_on_error= 1; /* avoid uninitialized variables */ var_set_query_get_value(&command, v); DBUG_VOID_RETURN; } @@ -3857,13 +3892,15 @@ void do_change_user(struct st_command *command) } if (!ds_user.length) + { dynstr_set(&ds_user, mysql->user); - if (!ds_passwd.length) - dynstr_set(&ds_passwd, mysql->passwd); + if (!ds_passwd.length) + dynstr_set(&ds_passwd, mysql->passwd); - if (!ds_db.length) - dynstr_set(&ds_db, mysql->db); + if (!ds_db.length) + dynstr_set(&ds_db, mysql->db); + } DBUG_PRINT("info",("connection: '%s' user: '%s' password: '%s' database: '%s'", cur_con->name, ds_user.str, ds_passwd.str, ds_db.str)); @@ -4886,11 +4923,11 @@ char *get_string(char **to_ptr, char **from_ptr, } -void set_reconnect(MYSQL* mysql, int val) +void set_reconnect(MYSQL* mysql, my_bool val) { my_bool reconnect= val; DBUG_ENTER("set_reconnect"); - DBUG_PRINT("info", ("val: %d", val)); + DBUG_PRINT("info", ("val: %d", (int) val)); #if MYSQL_VERSION_ID < 50000 mysql->reconnect= reconnect; #else @@ -6222,6 +6259,13 @@ static struct my_option my_long_options[] = {"view-protocol", OPT_VIEW_PROTOCOL, "Use views for select.", &view_protocol, &view_protocol, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", + (uchar**) &opt_plugin_dir, (uchar**) &opt_plugin_dir, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"default_auth", OPT_PLUGIN_DIR, + "Default authentication client-side plugin to use.", + (uchar**) &opt_default_auth, (uchar**) &opt_default_auth, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -6904,6 +6948,22 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql) /* + Handle situation where query is sent but there is no active connection + (e.g directly after disconnect). + + We emulate MySQL-compatible behaviour of sending something on a closed + connection. +*/ +static void handle_no_active_connection(struct st_command *command, + struct st_connection *cn, DYNAMIC_STRING *ds) +{ + handle_error(command, 2006, "MySQL server has gone away", "000000", ds); + cn->pending= FALSE; + var_set_errno(2006); +} + + +/* Run query using MySQL C API SYNOPSIS @@ -6929,11 +6989,7 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, if (!mysql) { - /* Emulate old behaviour of sending something on a closed connection */ - handle_error(command, 2006, "MySQL server has gone away", - "000000", ds); - cn->pending= FALSE; - var_set_errno(2006); + handle_no_active_connection(command, cn, ds); DBUG_VOID_RETURN; } @@ -7583,6 +7639,15 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) dynstr_append_mem(ds, "\n", 1); } + /* + Write the command to the result file before we execute the query + This is needed to be able to analyse the log if something goes + wrong + */ + log_file.write(&ds_res); + log_file.flush(); + dynstr_set(&ds_res, 0); + if (view_protocol_enabled && complete_query && match_re(&view_re, query)) @@ -7921,7 +7986,7 @@ void mark_progress(struct st_command* command __attribute__((unused)), die("Out of memory"); /* Milliseconds since start */ - end= longlong2str(timer, buf, 10); + end= longlong10_to_str(timer, buf, 10); dynstr_append_mem(&ds_progress, buf, (int)(end-buf)); dynstr_append_mem(&ds_progress, "\t", 1); @@ -8198,6 +8263,12 @@ int main(int argc, char **argv) if (opt_protocol) mysql_options(con->mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); + if (opt_plugin_dir && *opt_plugin_dir) + mysql_options(con->mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir); + + if (opt_default_auth && *opt_default_auth) + mysql_options(con->mysql, MYSQL_DEFAULT_AUTH, opt_default_auth); + #ifdef HAVE_OPENSSL if (opt_use_ssl) @@ -8742,7 +8813,7 @@ void timer_output(void) { char buf[32], *end; ulonglong timer= timer_now() - timer_start; - end= longlong2str(timer, buf, 10); + end= longlong10_to_str(timer, buf, 10); str_to_file(timer_file,buf, (int) (end-buf)); /* Timer has been written to the file, don't use it anymore */ timer_file= 0; @@ -8904,15 +8975,15 @@ void free_replace() typedef struct st_replace { - my_bool found; + int found; struct st_replace *next[256]; } REPLACE; typedef struct st_replace_found { - my_bool found; - char *replace_string; + int found; uint to_offset; int from_offset; + char *replace_string; } REPLACE_STRING; @@ -8944,7 +9015,7 @@ void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds, } /* Found a string that needs to be replaced */ - DBUG_PRINT("info", ("found: %d, to_offset: %d, from_offset: %d, string: %s", + DBUG_PRINT("info", ("found: %d, to_offset: %u, from_offset: %d, string: %s", rep_str->found, rep_str->to_offset, rep_str->from_offset, rep_str->replace_string)); @@ -10159,3 +10230,33 @@ static int setenv(const char *name, const char *value, int overwrite) return 0; } #endif + +/* + for the purpose of testing (see dialog.test) + we replace default mysql_authentication_dialog_ask function with the one, + that always reads from stdin with explicit echo. + +*/ +MYSQL_PLUGIN_EXPORT +char *mysql_authentication_dialog_ask(MYSQL *mysql, int type, + const char *prompt, + char *buf, int buf_len) +{ + char *s=buf; + + fputs(prompt, stdout); + fputs(" ", stdout); + + if (!fgets(buf, buf_len-1, stdin)) + buf[0]= 0; + else if (buf[0] && (s= strend(buf))[-1] == '\n') + s[-1]= 0; + + for (s= buf; *s; s++) + fputc(type == 2 ? '*' : *s, stdout); + + fputc('\n', stdout); + + return buf; +} + diff --git a/client/sql_string.cc b/client/sql_string.cc index d168af1cdf3..720b0332411 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -28,15 +28,6 @@ #ifdef HAVE_FCONVERT #include <floatingpoint.h> #endif - -/* - The following extern declarations are ok as these are interface functions - required by the string function -*/ - -extern void sql_alloc(size_t size); -extern void sql_element_free(void *ptr); - #include "sql_string.h" /***************************************************************************** diff --git a/client/sql_string.h b/client/sql_string.h index e72bf42a5ba..6d8269a4b31 100644 --- a/client/sql_string.h +++ b/client/sql_string.h @@ -17,6 +17,9 @@ /* This file is originally from the mysql distribution. Coded by monty */ +#ifndef CLIENT_SQL_STRING_H +#define CLIENT_SQL_STRING_H + #ifdef USE_PRAGMA_INTERFACE #pragma interface /* gcc class implementation */ #endif @@ -359,3 +362,5 @@ public: return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length); } }; + +#endif |