diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/CMakeLists.txt | 40 | ||||
-rw-r--r-- | client/client_priv.h | 5 | ||||
-rw-r--r-- | client/get_password.c | 208 | ||||
-rw-r--r-- | client/mysql.cc | 68 | ||||
-rw-r--r-- | client/mysql_plugin.c | 1 | ||||
-rw-r--r-- | client/mysql_upgrade.c | 2 | ||||
-rw-r--r-- | client/mysqladmin.cc | 31 | ||||
-rw-r--r-- | client/mysqlbinlog.cc | 351 | ||||
-rw-r--r-- | client/mysqlcheck.c | 3 | ||||
-rw-r--r-- | client/mysqldump.c | 46 | ||||
-rw-r--r-- | client/mysqlimport.c | 4 | ||||
-rw-r--r-- | client/mysqlshow.c | 4 | ||||
-rw-r--r-- | client/mysqlslap.c | 6 | ||||
-rw-r--r-- | client/mysqltest.cc | 552 |
14 files changed, 805 insertions, 516 deletions
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index c75abd4956d..e2329f505ab 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -20,20 +20,25 @@ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/mysys_ssl ${ZLIB_INCLUDE_DIR} ${SSL_INCLUDE_DIRS} - ${CMAKE_SOURCE_DIR}/libmysql ${CMAKE_SOURCE_DIR}/sql ${CMAKE_SOURCE_DIR}/strings ${MY_READLINE_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) +INCLUDE_DIRECTORIES(BEFORE + ${CMAKE_BINARY_DIR}/libmariadb/include + ${CMAKE_SOURCE_DIR}/libmariadb/include) + ## We will need libeay32.dll and ssleay32.dll when running client executables. COPY_OPENSSL_DLLS(copy_openssl_client) +SET(CLIENT_LIB mariadbclient mysys) + ADD_DEFINITIONS(${SSL_DEFINES}) MYSQL_ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc ${CMAKE_SOURCE_DIR}/sql/sql_string.cc) -TARGET_LINK_LIBRARIES(mysql mysqlclient) +TARGET_LINK_LIBRARIES(mysql ${CLIENT_LIB}) IF(UNIX) TARGET_LINK_LIBRARIES(mysql ${MY_READLINE_LIBRARY}) SET_TARGET_PROPERTIES(mysql PROPERTIES ENABLE_EXPORTS TRUE) @@ -41,39 +46,40 @@ ENDIF(UNIX) MYSQL_ADD_EXECUTABLE(mysqltest mysqltest.cc COMPONENT Test) SET_SOURCE_FILES_PROPERTIES(mysqltest.cc PROPERTIES COMPILE_FLAGS "-DTHREADS") -TARGET_LINK_LIBRARIES(mysqltest mysqlclient pcre pcreposix) +TARGET_LINK_LIBRARIES(mysqltest ${CLIENT_LIB} pcre pcreposix) SET_TARGET_PROPERTIES(mysqltest PROPERTIES ENABLE_EXPORTS TRUE) MYSQL_ADD_EXECUTABLE(mysqlcheck mysqlcheck.c) -TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient) +TARGET_LINK_LIBRARIES(mysqlcheck ${CLIENT_LIB}) MYSQL_ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c) -TARGET_LINK_LIBRARIES(mysqldump mysqlclient) +TARGET_LINK_LIBRARIES(mysqldump ${CLIENT_LIB}) + MYSQL_ADD_EXECUTABLE(mysqlimport mysqlimport.c) SET_SOURCE_FILES_PROPERTIES(mysqlimport.c PROPERTIES COMPILE_FLAGS "-DTHREADS") -TARGET_LINK_LIBRARIES(mysqlimport mysqlclient) +TARGET_LINK_LIBRARIES(mysqlimport ${CLIENT_LIB}) MYSQL_ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c COMPONENT Server) -TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient) +TARGET_LINK_LIBRARIES(mysql_upgrade ${CLIENT_LIB}) ADD_DEPENDENCIES(mysql_upgrade GenFixPrivs) MYSQL_ADD_EXECUTABLE(mysqlshow mysqlshow.c) -TARGET_LINK_LIBRARIES(mysqlshow mysqlclient) +TARGET_LINK_LIBRARIES(mysqlshow ${CLIENT_LIB}) MYSQL_ADD_EXECUTABLE(mysql_plugin mysql_plugin.c) -TARGET_LINK_LIBRARIES(mysql_plugin mysqlclient) +TARGET_LINK_LIBRARIES(mysql_plugin ${CLIENT_LIB}) MYSQL_ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc) -TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient) +TARGET_LINK_LIBRARIES(mysqlbinlog ${CLIENT_LIB}) -MYSQL_ADD_EXECUTABLE(mysqladmin mysqladmin.cc) -TARGET_LINK_LIBRARIES(mysqladmin mysqlclient) +MYSQL_ADD_EXECUTABLE(mysqladmin mysqladmin.cc ../sql/password.c) +TARGET_LINK_LIBRARIES(mysqladmin ${CLIENT_LIB}) MYSQL_ADD_EXECUTABLE(mysqlslap mysqlslap.c) SET_SOURCE_FILES_PROPERTIES(mysqlslap.c PROPERTIES COMPILE_FLAGS "-DTHREADS") -TARGET_LINK_LIBRARIES(mysqlslap mysqlclient) +TARGET_LINK_LIBRARIES(mysqlslap ${CLIENT_LIB}) # "WIN32" also covers 64 bit. "echo" is used in some files below "mysql-test/". IF(WIN32) @@ -82,10 +88,16 @@ ENDIF(WIN32) # async_example is just a code example, do not install it. ADD_EXECUTABLE(async_example async_example.c) -TARGET_LINK_LIBRARIES(async_example mysqlclient) +TARGET_LINK_LIBRARIES(async_example ${CLIENT_LIB}) SET_TARGET_PROPERTIES (mysqlcheck mysqldump mysqlimport mysql_upgrade mysqlshow mysqlslap mysql_plugin async_example PROPERTIES HAS_CXX TRUE) + +FOREACH(t mysql mysqltest mysqltest mysqlcheck mysqldump mysqlimport mysql_upgrade mysqlshow mysql_plugin mysqlbinlog + mysqladmin mysqlslap async_example) + ADD_DEPENDENCIES(${t} GenError ${CLIENT_LIB}) +ENDFOREACH() + ADD_DEFINITIONS(-DHAVE_DLOPEN) diff --git a/client/client_priv.h b/client/client_priv.h index 1419d9dfad9..ba1a1fddfae 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -24,6 +24,7 @@ #include <mysql.h> #include <errmsg.h> #include <my_getopt.h> +#include <mysql_version.h> #ifndef WEXITSTATUS # ifdef __WIN__ @@ -65,6 +66,10 @@ enum options_client OPT_MYSQLDUMP_SLAVE_APPLY, OPT_MYSQLDUMP_SLAVE_DATA, OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT, +#ifdef WHEN_FLASHBACK_REVIEW_READY + OPT_REVIEW, + OPT_REVIEW_DBNAME, OPT_REVIEW_TABLENAME, +#endif 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, diff --git a/client/get_password.c b/client/get_password.c deleted file mode 100644 index 8a507d94e9b..00000000000 --- a/client/get_password.c +++ /dev/null @@ -1,208 +0,0 @@ -/* Copyright (c) 2000, 2001, 2003, 2006, 2008 MySQL AB - Use is subject to license terms - - 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 - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -/* -** Ask for a password from tty -** This is an own file to avoid conflicts with curses -*/ -#include <my_global.h> -#include <my_sys.h> -#include "mysql.h" -#include <m_string.h> -#include <m_ctype.h> - -#ifdef HAVE_GETPASS -#ifdef HAVE_PWD_H -#include <pwd.h> -#endif /* HAVE_PWD_H */ -#else /* ! HAVE_GETPASS */ -#ifndef __WIN__ -#include <sys/ioctl.h> -#ifdef HAVE_TERMIOS_H /* For tty-password */ -#include <termios.h> -#define TERMIO struct termios -#else -#ifdef HAVE_TERMIO_H /* For tty-password */ -#include <termio.h> -#define TERMIO struct termio -#else -#include <sgtty.h> -#define TERMIO struct sgttyb -#endif -#endif -#ifdef alpha_linux_port -#include <asm/ioctls.h> /* QQ; Fix this in configure */ -#include <asm/termiobits.h> -#endif -#else -#include <conio.h> -#endif /* __WIN__ */ -#endif /* HAVE_GETPASS */ - -#ifdef HAVE_GETPASSPHRASE /* For Solaris */ -#define getpass(A) getpassphrase(A) -#endif - -#ifdef __WIN__ -/* were just going to fake it here and get input from - the keyboard */ - -char *get_tty_password(const char *opt_message) -{ - char to[80]; - char *pos=to,*end=to+sizeof(to)-1; - int i=0; - DBUG_ENTER("get_tty_password"); - _cputs(opt_message ? opt_message : "Enter password: "); - for (;;) - { - char tmp; - tmp=_getch(); - if (tmp == '\b' || (int) tmp == 127) - { - if (pos != to) - { - _cputs("\b \b"); - pos--; - continue; - } - } - if (tmp == '\n' || tmp == '\r' || tmp == 3) - break; - if (iscntrl(tmp) || pos == end) - continue; - _cputs("*"); - *(pos++) = tmp; - } - while (pos != to && isspace(pos[-1]) == ' ') - pos--; /* Allow dummy space at end */ - *pos=0; - _cputs("\n"); - DBUG_RETURN(my_strdup(to,MYF(MY_FAE))); -} - -#else - - -#ifndef HAVE_GETPASS -/* -** Can't use fgets, because readline will get confused -** length is max number of chars in to, not counting \0 -* to will not include the eol characters. -*/ - -static void get_password(char *to,uint length,int fd, my_bool echo) -{ - char *pos=to,*end=to+length; - - for (;;) - { - uchar tmp; - if (my_read(fd,&tmp,1,MYF(0)) != 1) - break; - if (tmp == '\b' || (int) tmp == 127) - { - if (pos != to) - { - if (echo) - { - fputs("\b \b",stderr); - fflush(stderr); - } - pos--; - continue; - } - } - if (tmp == '\n' || tmp == '\r' || tmp == 3) - break; - if (iscntrl(tmp) || pos == end) - continue; - if (echo) - { - fputc('*',stderr); - fflush(stderr); - } - *(pos++)= (char) tmp; - } - while (pos != to && isspace(pos[-1]) == ' ') - pos--; /* Allow dummy space at end */ - *pos=0; - return; -} - -#endif /* ! HAVE_GETPASS */ - - -char *get_tty_password(const char *opt_message) -{ -#ifdef HAVE_GETPASS - char *passbuff; -#else /* ! HAVE_GETPASS */ - TERMIO org,tmp; -#endif /* HAVE_GETPASS */ - char buff[80]; - - DBUG_ENTER("get_tty_password"); - -#ifdef HAVE_GETPASS - passbuff = getpass(opt_message ? opt_message : "Enter password: "); - - /* copy the password to buff and clear original (static) buffer */ - strnmov(buff, passbuff, sizeof(buff) - 1); -#ifdef _PASSWORD_LEN - memset(passbuff, 0, _PASSWORD_LEN); -#endif -#else - if (isatty(fileno(stderr))) - { - fputs(opt_message ? opt_message : "Enter password: ",stderr); - fflush(stderr); - } -#if defined(HAVE_TERMIOS_H) - tcgetattr(fileno(stdin), &org); - tmp = org; - tmp.c_lflag &= ~(ECHO | ISIG | ICANON); - tmp.c_cc[VMIN] = 1; - tmp.c_cc[VTIME] = 0; - tcsetattr(fileno(stdin), TCSADRAIN, &tmp); - get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stderr))); - tcsetattr(fileno(stdin), TCSADRAIN, &org); -#elif defined(HAVE_TERMIO_H) - ioctl(fileno(stdin), (int) TCGETA, &org); - tmp=org; - tmp.c_lflag &= ~(ECHO | ISIG | ICANON); - tmp.c_cc[VMIN] = 1; - tmp.c_cc[VTIME]= 0; - ioctl(fileno(stdin),(int) TCSETA, &tmp); - get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stderr))); - ioctl(fileno(stdin),(int) TCSETA, &org); -#else - gtty(fileno(stdin), &org); - tmp=org; - tmp.sg_flags &= ~ECHO; - tmp.sg_flags |= RAW; - stty(fileno(stdin), &tmp); - get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stderr))); - stty(fileno(stdin), &org); -#endif - if (isatty(fileno(stderr))) - fputc('\n',stderr); -#endif /* HAVE_GETPASS */ - - DBUG_RETURN(my_strdup(buff,MYF(MY_FAE))); -} - -#endif /*__WIN__*/ diff --git a/client/mysql.cc b/client/mysql.cc index 3a21e2857c9..e9a17a3f358 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1144,6 +1144,7 @@ int main(int argc,char *argv[]) outfile[0]=0; // no (default) outfile strmov(pager, "stdout"); // the default, if --pager wasn't given + { char *tmp=getenv("PAGER"); if (tmp && strlen(tmp)) @@ -1178,7 +1179,11 @@ int main(int argc,char *argv[]) load_defaults_or_exit("my", load_default_groups, &argc, &argv); defaults_argv=argv; if ((status.exit_status= get_options(argc, (char **) argv))) - mysql_end(-1); + { + free_defaults(defaults_argv); + my_end(0); + exit(status.exit_status); + } if (status.batch && !status.line_buff && !(status.line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, stdin))) @@ -1201,7 +1206,6 @@ int main(int argc,char *argv[]) glob_buffer.realloc(512); completion_hash_init(&ht, 128); init_alloc_root(&hash_mem_root, 16384, 0, MYF(0)); - bzero((char*) &mysql, sizeof(mysql)); if (sql_connect(current_host,current_db,current_user,opt_password, opt_silent)) { @@ -1891,6 +1895,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), usage(1); status.exit_status= 0; mysql_end(-1); + break; case 'I': case '?': usage(0); @@ -1964,7 +1969,7 @@ static int get_options(int argc, char **argv) connect_flag|= CLIENT_IGNORE_SPACE; if (opt_progress_reports) - connect_flag|= CLIENT_PROGRESS; + connect_flag|= CLIENT_PROGRESS_OBSOLETE; return(0); } @@ -3128,7 +3133,7 @@ static int com_help(String *buffer __attribute__((unused)), char *line __attribute__((unused))) { - reg1 int i, j; + int i, j; char * help_arg= strchr(line,' '), buff[32], *end; if (help_arg) { @@ -3497,7 +3502,6 @@ static char *fieldflags2str(uint f) { ff2s_check_flag(NUM); ff2s_check_flag(PART_KEY); ff2s_check_flag(GROUP); - ff2s_check_flag(UNIQUE); ff2s_check_flag(BINCMP); ff2s_check_flag(ON_UPDATE_NOW); #undef ff2s_check_flag @@ -3914,7 +3918,7 @@ print_table_data_vertically(MYSQL_RES *result) } tee_putc('\n', PAGER); } - else + else tee_fprintf(PAGER, "NULL\n"); } } @@ -4712,21 +4716,25 @@ sql_real_connect(char *host,char *database,char *user,char *password, } return -1; // Retryable } - - charset_info= mysql.charset; + + charset_info= get_charset_by_name(mysql.charset->name, MYF(0)); + connected=1; #ifndef EMBEDDED_LIBRARY - mysql.reconnect= debug_info_flag; // We want to know if this happens + mysql_options(&mysql, MYSQL_OPT_RECONNECT, &debug_info_flag); /* - CLIENT_PROGRESS is set only if we requsted it in mysql_real_connect() - and the server also supports it + CLIENT_PROGRESS_OBSOLETE is set only if we requested it in + mysql_real_connect() and the server also supports it */ - if (mysql.client_flag & CLIENT_PROGRESS) + if (mysql.client_flag & CLIENT_PROGRESS_OBSOLETE) mysql_options(&mysql, MYSQL_PROGRESS_CALLBACK, (void*) report_progress); #else - mysql.reconnect= 1; + { + my_bool reconnect= 1; + mysql_options(&mysql, MYSQL_OPT_RECONNECT, &reconnect); + } #endif #ifdef HAVE_READLINE build_completion_hash(opt_rehash, 1); @@ -5191,17 +5199,31 @@ static const char *construct_prompt() processed_prompt.append("unknown"); break; case 'h': + case 'H': { - const char *prompt; - prompt= connected ? mysql_get_host_info(&mysql) : "not_connected"; - if (strstr(prompt, "Localhost")) - processed_prompt.append("localhost"); - else - { - const char *end=strcend(prompt,' '); - processed_prompt.append(prompt, (uint) (end-prompt)); - } - break; + const char *prompt; + prompt= connected ? mysql_get_host_info(&mysql) : "not_connected"; + if (strstr(prompt, "Localhost") || strstr(prompt, "localhost ")) + { + if (*c == 'h') + processed_prompt.append("localhost"); + else + { + static char hostname[FN_REFLEN]; + if (hostname[0]) + processed_prompt.append(hostname); + else if (gethostname(hostname, sizeof(hostname)) == 0) + processed_prompt.append(hostname); + else + processed_prompt.append("gethostname(2) failed"); + } + } + else + { + const char *end=strcend(prompt,' '); + processed_prompt.append(prompt, (uint) (end-prompt)); + } + break; } case 'p': { diff --git a/client/mysql_plugin.c b/client/mysql_plugin.c index 76108c7a287..9cf4cd957fd 100644 --- a/client/mysql_plugin.c +++ b/client/mysql_plugin.c @@ -20,6 +20,7 @@ #include <mysql.h> #include <my_getopt.h> #include <my_dir.h> +#include <mysql_version.h> #define SHOW_VERSION "1.0.0" #define PRINT_VERSION do { printf("%s Ver %s Distrib %s\n", \ diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 5eb495774ce..0f153fde158 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -501,7 +501,7 @@ static void find_tool(char *tool_executable_name, const char *tool_name, last_fn_libchar -= 6; } - len= last_fn_libchar - self_name; + len= (int)(last_fn_libchar - self_name); my_snprintf(tool_executable_name, FN_REFLEN, "%.*s%c%s", len, self_name, FN_LIBCHAR, tool_name); diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index d4d40b0a0f2..5e7fb80b2b5 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -22,9 +22,10 @@ #include <my_pthread.h> /* because of signal() */ #include <sys/stat.h> #include <mysql.h> -#include <sql_common.h> +#include <mysql_version.h> #include <welcome_copyright_notice.h> #include <my_rnd.h> +#include <password.h> #define ADMIN_VERSION "9.1" #define MAX_MYSQL_VAR 512 @@ -33,9 +34,9 @@ char *host= NULL, *user= 0, *opt_password= 0, *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]; +char truncated_var_names[MAX_MYSQL_VAR+100][MAX_TRUNC_LENGTH]; +char ex_var_names[MAX_MYSQL_VAR+100][FN_REFLEN]; +ulonglong last_values[MAX_MYSQL_VAR+100]; static int interval=0; static my_bool option_force=0,interrupted=0,new_line=0, opt_compress= 0, opt_local= 0, opt_relative= 0, opt_verbose= 0, @@ -451,7 +452,7 @@ int main(int argc,char *argv[]) didn't signal for us to die. Otherwise, signal failure. */ - if (mysql.net.vio == 0) + if (mysql.net.pvio == 0) { if (option_wait && !interrupted) { @@ -530,7 +531,8 @@ static my_bool sql_connect(MYSQL *mysql, uint wait) if (mysql_real_connect(mysql,host,user,opt_password,NullS,tcp_port, unix_port, CLIENT_REMEMBER_OPTIONS)) { - mysql->reconnect= 1; + my_bool reconnect= 1; + mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect); if (info) { fputs("\n",stderr); @@ -884,7 +886,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) return -1; } - DBUG_ASSERT(mysql_num_rows(res) < MAX_MYSQL_VAR); + DBUG_ASSERT(mysql_num_rows(res) < MAX_MYSQL_VAR+100); if (!opt_vertical) print_header(res); @@ -1179,9 +1181,9 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } } if (old) - make_scrambled_password_323(crypted_pw, typed_password); + my_make_scrambled_password_323(crypted_pw, typed_password, strlen(typed_password)); else - make_scrambled_password(crypted_pw, typed_password); + my_make_scrambled_password(crypted_pw, typed_password, strlen(typed_password)); } else crypted_pw[0]=0; /* No password */ @@ -1290,7 +1292,9 @@ password_done: break; } case ADMIN_PING: - mysql->reconnect=0; /* We want to know of reconnects */ + { + my_bool reconnect= 0; + mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect); if (!mysql_ping(mysql)) { if (option_silent < 2) @@ -1300,7 +1304,8 @@ password_done: { if (mysql_errno(mysql) == CR_SERVER_GONE_ERROR) { - mysql->reconnect=1; + reconnect= 1; + mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect); if (!mysql_ping(mysql)) puts("connection was down, but mysqld is now alive"); } @@ -1311,8 +1316,10 @@ password_done: return -1; } } - mysql->reconnect=1; /* Automatic reconnect is default */ + reconnect=1; /* Automatic reconnect is default */ + mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect); break; + } default: my_printf_error(0, "Unknown command: '%-.60s'", error_flags, argv[0]); return 1; diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index bc13aa6c2cc..4c271b73b96 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -37,13 +37,12 @@ #include <sslopt-vars.h> /* That one is necessary for defines of OPTION_NO_FOREIGN_KEY_CHECKS etc */ #include "sql_priv.h" +#include "sql_basic_types.h" #include "log_event.h" #include "compat56.h" #include "sql_common.h" #include "my_dir.h" #include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE - - #include "sql_string.h" // needed for Rpl_filter #include "sql_list.h" // needed for Rpl_filter #include "rpl_filter.h" @@ -52,17 +51,26 @@ #include <algorithm> +#define my_net_write ma_net_write +#define net_flush ma_net_flush +#define cli_safe_read mysql_net_read_packet +#define my_net_read ma_net_read +extern "C" unsigned char *mysql_net_store_length(unsigned char *packet, size_t length); +#define net_store_length mysql_net_store_length + Rpl_filter *binlog_filter= 0; #define BIN_LOG_HEADER_SIZE 4 #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) - -#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES) - /* Needed for Rpl_filter */ CHARSET_INFO* system_charset_info= &my_charset_utf8_general_ci; +/* Needed for Flashback */ +DYNAMIC_ARRAY binlog_events; // Storing the events output string +DYNAMIC_ARRAY events_in_stmt; // Storing the events that in one statement +String stop_event_string; // Storing the STOP_EVENT output string + char server_version[SERVER_VERSION_LENGTH]; ulong server_id = 0; @@ -86,7 +94,7 @@ static const char *load_groups[]= static void error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); static void warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); -static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0; +static bool one_database=0, one_table=0, to_last_remote_log= 0, disable_log_bin= 0; static bool opt_hexdump= 0, opt_version= 0; const char *base64_output_mode_names[]= {"NEVER", "AUTO", "ALWAYS", "UNSPEC", "DECODE-ROWS", NullS}; @@ -96,6 +104,7 @@ TYPELIB base64_output_mode_typelib= static enum_base64_output_mode opt_base64_output_mode= BASE64_OUTPUT_UNSPEC; static char *opt_base64_output_mode_str= NullS; static char* database= 0; +static char* table= 0; static my_bool force_opt= 0, short_form= 0, remote_opt= 0; static my_bool debug_info_flag, debug_check_flag; static my_bool force_if_open_opt= 1; @@ -129,6 +138,12 @@ static MYSQL* mysql = NULL; static const char* dirname_for_local_load= 0; static bool opt_skip_annotate_row_events= 0; +static my_bool opt_flashback; +#ifdef WHEN_FLASHBACK_REVIEW_READY +static my_bool opt_flashback_review; +static char *flashback_review_dbname, *flashback_review_tablename; +#endif + /** Pointer to the Format_description_log_event of the currently active binlog. @@ -589,7 +604,7 @@ Exit_status Load_log_processor::process_first_event(const char *bname, Exit_status Load_log_processor::process(Create_file_log_event *ce) { const char *bname= ce->fname + dirname_length(ce->fname); - uint blen= ce->fname_len - (bname-ce->fname); + size_t blen= ce->fname_len - (bname-ce->fname); return process_first_event(bname, blen, ce->block, ce->block_len, ce->file_id, ce); @@ -788,6 +803,23 @@ print_skip_replication_statement(PRINT_EVENT_INFO *pinfo, const Log_event *ev) } /** + Indicates whether the given table should be filtered out, + according to the --table=X option. + + @param log_tblname Name of table. + + @return nonzero if the table with the given name should be + filtered out, 0 otherwise. +*/ +static bool shall_skip_table(const char *log_tblname) +{ + return one_table && + (log_tblname != NULL) && + strcmp(log_tblname, table); +} + + +/** Prints the given event in base64 format. The header is printed to the head cache and the body is printed to @@ -863,6 +895,25 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, print_event_info->m_table_map_ignored.get_table(table_id); bool skip_event= (ignored_map != NULL); + if (opt_flashback) + { + Rows_log_event *e= (Rows_log_event*) ev; + // The last Row_log_event will be the first event in Flashback + if (is_stmt_end) + e->clear_flags(Rows_log_event::STMT_END_F); + // The first Row_log_event will be the last event in Flashback + if (events_in_stmt.elements == 0) + e->set_flags(Rows_log_event::STMT_END_F); + // Update the temp_buf + e->update_flags(); + + if (insert_dynamic(&events_in_stmt, (uchar *) &ev)) + { + error("Out of memory: can't allocate memory to store the flashback events."); + exit(1); + } + } + /* end of statement check: i) destroy/free ignored maps @@ -914,7 +965,36 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, if (skip_event) return 0; - return print_base64(print_event_info, ev); + if (!opt_flashback) + return print_base64(print_event_info, ev); + else + { + if (is_stmt_end) + { + bool res= false; + Log_event *e= NULL; + + // Print the row_event from the last one to the first one + for (uint i= events_in_stmt.elements; i > 0; --i) + { + e= *(dynamic_element(&events_in_stmt, i - 1, Log_event**)); + res= res || print_base64(print_event_info, e); + } + // Copy all output into the Log_event + ev->output_buf.copy(e->output_buf); + // Delete Log_event + for (uint i= 0; i < events_in_stmt.elements-1; ++i) + { + e= *(dynamic_element(&events_in_stmt, i, Log_event**)); + delete e; + } + reset_dynamic(&events_in_stmt); + + return res; + } + } + + return 0; } @@ -949,6 +1029,12 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, Exit_status retval= OK_CONTINUE; IO_CACHE *const head= &print_event_info->head_cache; + /* Bypass flashback settings to event */ + ev->is_flashback= opt_flashback; +#ifdef WHEN_FLASHBACK_REVIEW_READY + ev->need_flashback_review= opt_flashback_review; +#endif + /* Format events are not concerned by --offset and such, we always need to read them to be able to process the wanted events. @@ -985,7 +1071,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, retval= OK_STOP; goto end; } - if (!short_form) + if (!short_form && !opt_flashback) fprintf(result_file, "# at %s\n",llstr(pos,ll_buff)); if (!opt_hexdump) @@ -999,6 +1085,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, switch (ev_type) { case QUERY_EVENT: + case QUERY_COMPRESSED_EVENT: { Query_log_event *qe= (Query_log_event*)ev; if (!qe->is_trans_keyword()) @@ -1210,12 +1297,128 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, case TABLE_MAP_EVENT: { Table_map_log_event *map= ((Table_map_log_event *)ev); - if (shall_skip_database(map->get_db_name())) + if (shall_skip_database(map->get_db_name()) || + shall_skip_table(map->get_table_name())) { print_event_info->m_table_map_ignored.set_table(map->get_table_id(), map); destroy_evt= FALSE; goto end; } +#ifdef WHEN_FLASHBACK_REVIEW_READY + /* Create review table for Flashback */ + if (opt_flashback_review) + { + // Check if the table was already created? + Table_map_log_event *exist_table; + exist_table= print_event_info->m_table_map.get_table(map->get_table_id()); + + if (!exist_table) + { + + MYSQL *conn; + MYSQL_RES *res; + MYSQL_ROW row; + char tmp_sql[8096]; + int tmp_sql_offset; + + conn = mysql_init(NULL); + if (!mysql_real_connect(conn, host, user, pass, + map->get_db_name(), port, sock, 0)) + { + fprintf(stderr, "%s\n", mysql_error(conn)); + exit(1); + } + + if (mysql_query(conn, "SET group_concat_max_len=10000;")) + { + fprintf(stderr, "%s\n", mysql_error(conn)); + exit(1); + } + + memset(tmp_sql, 0, sizeof(tmp_sql)); + sprintf(tmp_sql, " " + "SELECT Group_concat(cols) " + "FROM (SELECT 'op_type char(1)' cols " + " UNION ALL " + " SELECT Concat('`', column_name, '_old` ', column_type, ' ', " + " IF(character_set_name IS NOT NULL, " + " Concat('character set ', character_set_name, ' '), ' '), " + " IF(collation_name IS NOT NULL, " + " Concat('collate ', collation_name, ' '), ' ')) cols " + " FROM information_schema.columns " + " WHERE table_schema = '%s' " + " AND table_name = '%s' " + " UNION ALL " + " SELECT Concat('`', column_name, '_new` ', column_type, ' ', " + " IF(character_set_name IS NOT NULL, " + " Concat('character set ', character_set_name, ' '), ' '), " + " IF(collation_name IS NOT NULL, " + " Concat('collate ', collation_name, ' '), ' ')) cols " + " FROM information_schema.columns " + " WHERE table_schema = '%s' " + " AND table_name = '%s') tmp;", + map->get_db_name(), map->get_table_name(), + map->get_db_name(), map->get_table_name()); + + if (mysql_query(conn, tmp_sql)) + { + fprintf(stderr, "%s\n", mysql_error(conn)); + exit(1); + } + res = mysql_use_result(conn); + if ((row = mysql_fetch_row(res)) != NULL) // only one row + { + if (flashback_review_dbname) + { + ev->set_flashback_review_dbname(flashback_review_dbname); + } + else + { + ev->set_flashback_review_dbname(map->get_db_name()); + } + if (flashback_review_tablename) + { + ev->set_flashback_review_tablename(flashback_review_tablename); + } + else + { + memset(tmp_sql, 0, sizeof(tmp_sql)); + sprintf(tmp_sql, "__%s", map->get_table_name()); + ev->set_flashback_review_tablename(tmp_sql); + } + memset(tmp_sql, 0, sizeof(tmp_sql)); + tmp_sql_offset= sprintf(tmp_sql, "CREATE TABLE IF NOT EXISTS"); + tmp_sql_offset+= sprintf(tmp_sql + tmp_sql_offset, " `%s`.`%s` (%s) %s", + ev->get_flashback_review_dbname(), + ev->get_flashback_review_tablename(), + row[0], + print_event_info->delimiter); + } + fprintf(result_file, "%s\n", tmp_sql); + mysql_free_result(res); + mysql_close(conn); + } + else + { + char tmp_str[128]; + + if (flashback_review_dbname) + ev->set_flashback_review_dbname(flashback_review_dbname); + else + ev->set_flashback_review_dbname(map->get_db_name()); + + if (flashback_review_tablename) + ev->set_flashback_review_tablename(flashback_review_tablename); + else + { + memset(tmp_str, 0, sizeof(tmp_str)); + sprintf(tmp_str, "__%s", map->get_table_name()); + ev->set_flashback_review_tablename(tmp_str); + } + } + } +#endif + /* The Table map is to be printed, so it's just the time when we may print the kept Annotate event (if there is any). @@ -1232,6 +1435,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, } if (print_base64(print_event_info, ev)) goto err; + if (opt_flashback) + reset_dynamic(&events_in_stmt); break; } case WRITE_ROWS_EVENT: @@ -1240,11 +1445,20 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, case WRITE_ROWS_EVENT_V1: case UPDATE_ROWS_EVENT_V1: case DELETE_ROWS_EVENT_V1: + case WRITE_ROWS_COMPRESSED_EVENT: + case DELETE_ROWS_COMPRESSED_EVENT: + case UPDATE_ROWS_COMPRESSED_EVENT: + case WRITE_ROWS_COMPRESSED_EVENT_V1: + case UPDATE_ROWS_COMPRESSED_EVENT_V1: + case DELETE_ROWS_COMPRESSED_EVENT_V1: { Rows_log_event *e= (Rows_log_event*) ev; + bool is_stmt_end= e->get_flags(Rows_log_event::STMT_END_F); if (print_row_event(print_event_info, ev, e->get_table_id(), e->get_flags(Rows_log_event::STMT_END_F))) goto err; + if (!is_stmt_end) + destroy_evt= FALSE; break; } case PRE_GA_WRITE_ROWS_EVENT: @@ -1252,9 +1466,12 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, case PRE_GA_UPDATE_ROWS_EVENT: { Old_rows_log_event *e= (Old_rows_log_event*) ev; + bool is_stmt_end= e->get_flags(Rows_log_event::STMT_END_F); if (print_row_event(print_event_info, ev, e->get_table_id(), e->get_flags(Old_rows_log_event::STMT_END_F))) goto err; + if (!is_stmt_end) + destroy_evt= FALSE; break; } case START_ENCRYPTION_EVENT: @@ -1284,6 +1501,38 @@ end: */ if (ev) { + /* Holding event output if needed */ + if (!ev->output_buf.is_empty()) + { + LEX_STRING tmp_str; + + tmp_str.length= ev->output_buf.length(); + tmp_str.str= ev->output_buf.release(); + + if (opt_flashback) + { + if (ev_type == STOP_EVENT) + stop_event_string.reset(tmp_str.str, tmp_str.length, tmp_str.length, + &my_charset_bin); + else + { + if (insert_dynamic(&binlog_events, (uchar *) &tmp_str)) + { + error("Out of memory: can't allocate memory to store the flashback events."); + exit(1); + } + } + } + else + { + my_fwrite(result_file, (const uchar *) tmp_str.str, tmp_str.length, + MYF(MY_NABP)); + my_free(tmp_str.str); + } + } + + if (remote_opt) + ev->temp_buf= 0; if (destroy_evt) /* destroy it later if not set (ignored table map) */ delete ev; } @@ -1342,6 +1591,13 @@ static struct my_option my_options[] = "already have. NOTE: you will need a SUPER privilege to use this option.", &disable_log_bin, &disable_log_bin, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"flashback", 'B', "Flashback feature can rollback you committed data to a special time point.", +#ifdef WHEN_FLASHBACK_REVIEW_READY + "before Flashback feature writing a row, original row can insert to review-dbname.review-tablename," + "and mysqlbinlog will login mysql by user(-u) and password(-p) and host(-h).", +#endif + &opt_flashback, &opt_flashback, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, {"force-if-open", 'F', "Force if binlog was not closed properly.", &force_if_open_opt, &force_if_open_opt, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -1385,6 +1641,19 @@ static struct my_option my_options[] = "prefix for the file names.", &result_file_name, &result_file_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#ifdef WHEN_FLASHBACK_REVIEW_READY + {"review", opt_flashback_review, "Print review sql in output file.", + &opt_flashback_review, &opt_flashback_review, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, + {"review-dbname", opt_flashback_flashback_review_dbname, + "Writing flashback original row data into this db", + &flashback_review_dbname, &flashback_review_dbname, + 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"review-tablename", opt_flashback_flashback_review_tablename, + "Writing flashback original row data into this table", + &flashback_review_tablename, &flashback_review_tablename, + 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#endif {"server-id", 0, "Extract only binlog entries created by the server having the given id.", &server_id, &server_id, 0, GET_ULONG, @@ -1448,6 +1717,9 @@ static struct my_option my_options[] = &stop_position, &stop_position, 0, GET_ULL, REQUIRED_ARG, (longlong)(~(my_off_t)0), BIN_LOG_HEADER_SIZE, (ulonglong)(~(my_off_t)0), 0, 0, 0}, + {"table", 'T', "List entries for just this table (local log only).", + &table, &table, 0, GET_STR_ALLOC, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, {"to-last-log", 't', "Requires -R. Will not stop at the end of the \ requested binlog but rather continue printing until the end of the last \ binlog of the MySQL server. If you send the output to the same MySQL server, \ @@ -1557,6 +1829,7 @@ static void cleanup() { my_free(pass); my_free(database); + my_free(table); my_free(host); my_free(user); my_free(const_cast<char*>(dirname_for_local_load)); @@ -1627,6 +1900,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; #endif #include <sslopt-case.h> + case 'B': + opt_flashback= 1; + break; case 'd': one_database = 1; break; @@ -1648,6 +1924,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'R': remote_opt= 1; break; + case 'T': + one_table= 1; + break; case OPT_MYSQL_PROTOCOL: if ((opt_protocol= find_type_with_warning(argument, &sql_protocol_typelib, opt->name)) <= 0) @@ -1656,6 +1935,11 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), exit(1); } break; +#ifdef WHEN_FLASHBACK_REVIEW_READY + case opt_flashback_review: + opt_flashback_review= 1; + break; +#endif case OPT_START_DATETIME: start_datetime= convert_str_to_timestamp(start_datetime_str); break; @@ -1778,6 +2062,7 @@ static int parse_args(int *argc, char*** argv) */ static Exit_status safe_connect() { + my_bool reconnect= 1; /* Close any old connections to MySQL */ if (mysql) mysql_close(mysql); @@ -1823,7 +2108,7 @@ static Exit_status safe_connect() error("Failed on connect: %s", mysql_error(mysql)); return ERROR_STOP; } - mysql->reconnect= 1; + mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect); return OK_CONTINUE; } @@ -1862,7 +2147,7 @@ static Exit_status dump_log_entries(const char* logname) dump_local_log_entries(&print_event_info, logname)); /* Set delimiter back to semicolon */ - if (!opt_raw_mode) + if (!opt_raw_mode && !opt_flashback) fprintf(result_file, "DELIMITER ;\n"); strmov(print_event_info.delimiter, ";"); return rc; @@ -2650,8 +2935,6 @@ end: return retval; } -/* Used in sql_alloc(). Inited and freed in main() */ -MEM_ROOT s_mem_root; int main(int argc, char** argv) { @@ -2665,7 +2948,6 @@ int main(int argc, char** argv) my_init_time(); // for time functions tzset(); // set tzname - init_alloc_root(&s_mem_root, 16384, 0, MYF(0)); load_defaults_or_exit("my", load_groups, &argc, &argv); defaults_argv= argv; @@ -2699,6 +2981,13 @@ int main(int argc, char** argv) my_set_max_open_files(open_files_limit); + if (opt_flashback) + { + my_init_dynamic_array(&binlog_events, sizeof(LEX_STRING), 1024, 1024, + MYF(0)); + my_init_dynamic_array(&events_in_stmt, sizeof(Rows_log_event*), 1024, 1024, + MYF(0)); + } if (opt_stop_never) to_last_remote_log= TRUE; @@ -2797,6 +3086,30 @@ int main(int argc, char** argv) start_position= BIN_LOG_HEADER_SIZE; } + /* + If enable flashback, need to print the events from the end to the + beginning + */ + if (opt_flashback) + { + for (uint i= binlog_events.elements; i > 0; --i) + { + LEX_STRING *event_str= dynamic_element(&binlog_events, i - 1, + LEX_STRING*); + fprintf(result_file, "%s", event_str->str); + my_free(event_str->str); + } + fprintf(result_file, "COMMIT\n/*!*/;\n"); + delete_dynamic(&binlog_events); + delete_dynamic(&events_in_stmt); + } + + /* Set delimiter back to semicolon */ + if (!stop_event_string.is_empty()) + fprintf(result_file, "%s", stop_event_string.ptr()); + if (!opt_raw_mode && opt_flashback) + fprintf(result_file, "DELIMITER ;\n"); + if (!opt_raw_mode) { /* @@ -2824,7 +3137,6 @@ int main(int argc, char** argv) my_fclose(result_file, MYF(0)); cleanup(); free_annotate_event(); - free_root(&s_mem_root, MYF(0)); free_defaults(defaults_argv); my_free_open_file_info(); load_processor.destroy(); @@ -2845,11 +3157,6 @@ err: } -void *sql_alloc(size_t size) -{ - return alloc_root(&s_mem_root, size); -} - uint dummy1() { return 1; } struct encryption_service_st encryption_handler= { @@ -2872,6 +3179,8 @@ struct encryption_service_st encryption_handler= #include "my_decimal.h" #include "decimal.c" #include "my_decimal.cc" +#include "../sql-common/my_time.c" +#include "password.c" #include "log_event.cc" #include "log_event_old.cc" #include "rpl_utility.cc" diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index a4410eba8aa..45ad2612d44 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1077,6 +1077,7 @@ static void print_result() static int dbConnect(char *host, char *user, char *passwd) { + my_bool reconnect= 1; DBUG_ENTER("dbConnect"); if (verbose > 1) { @@ -1115,7 +1116,7 @@ static int dbConnect(char *host, char *user, char *passwd) DBerror(&mysql_connection, "when trying to connect"); DBUG_RETURN(1); } - mysql_connection.reconnect= 1; + mysql_options(&mysql_connection, MYSQL_OPT_RECONNECT, &reconnect); DBUG_RETURN(0); } /* dbConnect */ diff --git a/client/mysqldump.c b/client/mysqldump.c index f67e52c1b12..f64acb044f5 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2017, MariaDB + Copyright (c) 2010, 2017, MariaDB Corporation. 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 @@ -113,7 +113,8 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_no_data_m opt_slave_apply= 0, opt_include_master_host_port= 0, opt_events= 0, opt_comments_used= 0, - opt_alltspcs=0, opt_notspcs= 0, opt_logging; + opt_alltspcs=0, opt_notspcs= 0, opt_logging, + opt_drop_trigger= 0 ; static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0; static ulong opt_max_allowed_packet, opt_net_buffer_length; static MYSQL mysql_connection,*mysql=0; @@ -198,12 +199,12 @@ const char *compatible_mode_names[]= }; #define MASK_ANSI_QUOTES \ (\ - (1<<2) | /* POSTGRESQL */\ - (1<<3) | /* ORACLE */\ - (1<<4) | /* MSSQL */\ - (1<<5) | /* DB2 */\ - (1<<6) | /* MAXDB */\ - (1<<10) /* ANSI */\ + (1U<<2) | /* POSTGRESQL */\ + (1U<<3) | /* ORACLE */\ + (1U<<4) | /* MSSQL */\ + (1U<<5) | /* DB2 */\ + (1U<<6) | /* MAXDB */\ + (1U<<10) /* ANSI */\ ) TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1, "", compatible_mode_names, NULL}; @@ -232,6 +233,9 @@ static struct my_option my_long_options[] = {"add-drop-table", OPT_DROP, "Add a DROP TABLE before each create.", &opt_drop, &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + {"add-drop-trigger", 0, "Add a DROP TRIGGER before each create.", + &opt_drop_trigger, &opt_drop_trigger, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, + 0}, {"add-locks", OPT_LOCKS, "Add locks around INSERT statements.", &opt_lock, &opt_lock, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -243,8 +247,8 @@ static struct my_option my_long_options[] = &opt_slave_apply, &opt_slave_apply, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"character-sets-dir", OPT_CHARSETS_DIR, - "Directory for character set files.", &charsets_dir, - &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + "Directory for character set files.", (char **)&charsets_dir, + (char **)&charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"comments", 'i', "Write additional information.", &opt_comments, &opt_comments, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -281,8 +285,8 @@ static struct my_option my_long_options[] = {"debug", '#', "This is a non-debug version. Catch this and exit.", 0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0}, #else - {"debug", '#', "Output debug log.", &default_dbug_option, - &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"debug", '#', "Output debug log.", (char *)&default_dbug_option, + (char *)&default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.", &debug_check_flag, &debug_check_flag, 0, @@ -1668,6 +1672,7 @@ static void maybe_exit(int error) static int connect_to_db(char *host, char *user,char *passwd) { char buff[20+FN_REFLEN]; + my_bool reconnect; DBUG_ENTER("connect_to_db"); verbose_msg("-- Connecting to %s...\n", host ? host : "localhost"); @@ -1722,7 +1727,8 @@ static int connect_to_db(char *host, char *user,char *passwd) As we're going to set SQL_MODE, it would be lost on reconnect, so we cannot reconnect. */ - mysql->reconnect= 0; + reconnect= 0; + mysql_options(&mysql_connection, MYSQL_OPT_RECONNECT, &reconnect); my_snprintf(buff, sizeof(buff), "/*!40100 SET @@SQL_MODE='%s' */", compatible_mode_normal_str); if (mysql_query_with_error_report(mysql, 0, buff)) @@ -3283,6 +3289,10 @@ static void dump_trigger_old(FILE *sql_file, MYSQL_RES *show_triggers_rs, if (opt_compact) fprintf(sql_file, "/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;\n"); + if (opt_drop_trigger) + fprintf(sql_file, "/*!50032 DROP TRIGGER IF EXISTS %s */;\n", + (*show_trigger_row)[0]); + fprintf(sql_file, "DELIMITER ;;\n" "/*!50003 SET SESSION SQL_MODE=\"%s\" */;;\n" @@ -3363,6 +3373,10 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs, switch_sql_mode(sql_file, ";", row[1]); + if (opt_drop_trigger) + fprintf(sql_file, "/*!50032 DROP TRIGGER IF EXISTS %s */;\n", + row[0]); + query_str= cover_definer_clause(row[2], strlen(row[2]), C_STRING_WITH_LEN("50017"), C_STRING_WITH_LEN("50003"), @@ -5480,7 +5494,7 @@ static ulong find_set(TYPELIB *lib, const char *x, size_t length, *err_len= var_len; } else - found|= ((longlong) 1 << (find - 1)); + found|= 1UL << (find - 1); if (pos == end) break; start= pos + 1; @@ -5723,7 +5737,7 @@ static int replace(DYNAMIC_STRING *ds_str, return 1; init_dynamic_string_checked(&ds_tmp, "", ds_str->length + replace_len, 256); - dynstr_append_mem_checked(&ds_tmp, ds_str->str, start - ds_str->str); + dynstr_append_mem_checked(&ds_tmp, ds_str->str, (uint)(start - ds_str->str)); dynstr_append_mem_checked(&ds_tmp, replace_str, replace_len); dynstr_append_checked(&ds_tmp, start + search_len); dynstr_set_checked(ds_str, ds_tmp.str); @@ -6150,7 +6164,7 @@ int main(int argc, char **argv) goto err; /* - No reason to explicitely COMMIT the transaction, neither to explicitely + No reason to explicitly COMMIT the transaction, neither to explicitly UNLOCK TABLES: these will be automatically be done by the server when we disconnect now. Saves some code here, some network trips, adds nothing to server. diff --git a/client/mysqlimport.c b/client/mysqlimport.c index a9c24e20b0a..02caf2df198 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -424,6 +424,7 @@ static MYSQL *db_connect(char *host, char *database, char *user, char *passwd) { MYSQL *mysql; + my_bool reconnect; if (verbose) fprintf(stdout, "Connecting to %s\n", host ? host : "localhost"); if (opt_use_threads && !lock_tables) @@ -479,7 +480,8 @@ static MYSQL *db_connect(char *host, char *database, ignore_errors=0; /* NO RETURN FROM db_error */ db_error(mysql); } - mysql->reconnect= 0; + reconnect= 0; + mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect); if (verbose) fprintf(stdout, "Selecting database %s\n", database); if (mysql_select_db(mysql, database)) diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 95ee8d697f3..65b915655a6 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -68,6 +68,7 @@ int main(int argc, char **argv) my_bool first_argument_uses_wildcards=0; char *wild; MYSQL mysql; + my_bool reconnect; static char **defaults_argv; MY_INIT(argv[0]); sf_leaking_memory=1; /* don't report memory leaks on early exits */ @@ -154,7 +155,8 @@ int main(int argc, char **argv) error= 1; goto error; } - mysql.reconnect= 1; + reconnect= 1; + mysql_options(&mysql, MYSQL_OPT_RECONNECT, &reconnect); switch (argc) { case 0: error=list_dbs(&mysql,wild); break; diff --git a/client/mysqlslap.c b/client/mysqlslap.c index fd30776446d..20215b17bdc 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -583,8 +583,8 @@ static struct my_option my_long_options[] = &auto_generate_sql_number, &auto_generate_sql_number, 0, GET_ULL, REQUIRED_ARG, 100, 0, 0, 0, 0, 0}, {"character-sets-dir", OPT_CHARSETS_DIR, - "Directory for character set files.", &charsets_dir, - &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + "Directory for character set files.", (char **)&charsets_dir, + (char **)&charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"commit", OPT_SLAP_COMMIT, "Commit records every X number of statements.", &commit_rate, &commit_rate, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -817,7 +817,7 @@ get_random_string(char *buf) DBUG_ENTER("get_random_string"); for (x= RAND_STRING_SIZE; x > 0; x--) *buf_ptr++= ALPHANUMERICS[random() % ALPHANUMERICS_SIZE]; - DBUG_RETURN(buf_ptr - buf); + DBUG_RETURN((uint)(buf_ptr - buf)); } diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 32532c34835..e805fc61a54 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -49,7 +49,7 @@ #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif -#ifdef __WIN__ +#ifdef _WIN32 #include <direct.h> #endif #include <signal.h> @@ -57,7 +57,7 @@ #include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE -#ifdef __WIN__ +#ifdef _WIN32 #include <crtdbg.h> #define SIGNAL_FMT "exception 0x%x" #else @@ -82,7 +82,7 @@ static my_bool non_blocking_api_enabled= 0; #define MAX_DELIMITER_LENGTH 16 #define DEFAULT_MAX_CONN 64 -#define DIE_BUFF_SIZE 8192 +#define DIE_BUFF_SIZE 256*1024 /* Flags controlling send and reap */ #define QUERY_SEND_FLAG 1 @@ -125,9 +125,10 @@ static my_bool view_protocol= 0, view_protocol_enabled= 0; static my_bool cursor_protocol= 0, cursor_protocol_enabled= 0; static my_bool parsing_disabled= 0; static my_bool display_result_vertically= FALSE, display_result_lower= FALSE, - display_metadata= FALSE, display_result_sorted= FALSE; + display_metadata= FALSE, display_result_sorted= FALSE, + display_session_track_info= FALSE; static my_bool disable_query_log= 0, disable_result_log= 0; -static my_bool disable_connect_log= 1; +static my_bool disable_connect_log= 0; static my_bool disable_warnings= 0, disable_column_names= 0; static my_bool prepare_warnings_enabled= 0; static my_bool disable_info= 1; @@ -153,6 +154,7 @@ static struct property prop_list[] = { { &abort_on_error, 0, 1, 0, "$ENABLED_ABORT_ON_ERROR" }, { &disable_connect_log, 0, 1, 1, "$ENABLED_CONNECT_LOG" }, { &disable_info, 0, 1, 1, "$ENABLED_INFO" }, + { &display_session_track_info, 0, 1, 1, "$ENABLED_STATE_CHANGE_INFO" }, { &display_metadata, 0, 0, 0, "$ENABLED_METADATA" }, { &ps_protocol_enabled, 0, 0, 0, "$ENABLED_PS_PROTOCOL" }, { &disable_query_log, 0, 0, 1, "$ENABLED_QUERY_LOG" }, @@ -166,6 +168,7 @@ enum enum_prop { P_ABORT= 0, P_CONNECT, P_INFO, + P_SESSION_TRACK, P_META, P_PS, P_QUERY, @@ -191,6 +194,8 @@ static char global_subst_from[200]; static char global_subst_to[200]; static char *global_subst= NULL; static MEM_ROOT require_file_root; +static const my_bool my_true= 1; +static const my_bool my_false= 0; /* Block stack */ enum block_cmd { @@ -360,6 +365,7 @@ enum enum_commands { Q_WAIT_FOR_SLAVE_TO_STOP, Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS, Q_ENABLE_INFO, Q_DISABLE_INFO, + Q_ENABLE_SESSION_TRACK_INFO, Q_DISABLE_SESSION_TRACK_INFO, Q_ENABLE_METADATA, Q_DISABLE_METADATA, Q_ENABLE_COLUMN_NAMES, Q_DISABLE_COLUMN_NAMES, Q_EXEC, Q_DELIMITER, @@ -382,6 +388,7 @@ enum enum_commands { Q_RESULT_FORMAT_VERSION, Q_MOVE_FILE, Q_REMOVE_FILES_WILDCARD, Q_SEND_EVAL, Q_ENABLE_PREPARE_WARNINGS, Q_DISABLE_PREPARE_WARNINGS, + Q_RESET_CONNECTION, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ Q_COMMENT_WITH_COMMAND, @@ -433,6 +440,8 @@ const char *command_names[]= "disable_warnings", "enable_info", "disable_info", + "enable_session_track_info", + "disable_session_track_info", "enable_metadata", "disable_metadata", "enable_column_names", @@ -466,7 +475,7 @@ const char *command_names[]= "copy_file", "perl", "die", - + /* Don't execute any more commands, compare result */ "exit", "skip", @@ -489,6 +498,7 @@ const char *command_names[]= "send_eval", "enable_prepare_warnings", "disable_prepare_warnings", + "reset_connection", 0 }; @@ -572,15 +582,17 @@ struct st_replace *glob_replace= 0; void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds, const char *from, int len); -static void cleanup_and_exit(int exit_code) __attribute__((noreturn)); +ATTRIBUTE_NORETURN +static void cleanup_and_exit(int exit_code); -void really_die(const char *msg) __attribute__((noreturn)); +ATTRIBUTE_NORETURN +void really_die(const char *msg); void report_or_die(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2); -void die(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2) - __attribute__((noreturn)); +ATTRIBUTE_NORETURN ATTRIBUTE_FORMAT(printf, 1, 2) +void die(const char *fmt, ...); static void make_error_message(char *buf, size_t len, const char *fmt, va_list args); -void abort_not_supported_test(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2) - __attribute__((noreturn)); +ATTRIBUTE_NORETURN ATTRIBUTE_FORMAT(printf, 1, 2) +void abort_not_supported_test(const char *fmt, ...); void verbose_msg(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2); void log_msg(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2); @@ -600,11 +612,11 @@ void do_eval(DYNAMIC_STRING *query_eval, const char *query, void str_to_file(const char *fname, char *str, int size); void str_to_file2(const char *fname, char *str, int size, my_bool append); -void fix_win_paths(const char *val, size_t len); +void fix_win_paths(char *val, size_t len); const char *get_errname_from_code (uint error_code); int multi_reg_replace(struct st_replace_regex* r,char* val); -#ifdef __WIN__ +#ifdef _WIN32 void free_tmp_sh_file(); void free_win_path_patterns(); #endif @@ -704,7 +716,7 @@ public: DBUG_ASSERT(ds->str); #ifdef EXTRA_DEBUG - DBUG_PRINT("QQ", ("str: %*s", (int) ds->length, ds->str)); + DBUG_PRINT("extra", ("str: %*s", (int) ds->length, ds->str)); #endif if (fwrite(ds->str, 1, ds->length, m_file) != ds->length) @@ -763,7 +775,7 @@ public: if (show_from != buf) { // The last new line was found in this buf, adjust offset - show_offset+= (show_from - buf) + 1; + show_offset+= (int)(show_from - buf) + 1; DBUG_PRINT("info", ("adjusted offset to %d", show_offset)); } DBUG_PRINT("info", ("show_offset: %d", show_offset)); @@ -832,6 +844,47 @@ void revert_properties(); static void handle_no_active_connection(struct st_command* command, struct st_connection *cn, DYNAMIC_STRING *ds); + +/* Wrapper for fgets.Strips \r off newlines on Windows. + Should be used with together with my_popen(). +*/ +static char *my_fgets(char * s, int n, FILE * stream, int *len) +{ + char *buf = fgets(s, n, stream); + if (!buf) + { + *len= 0; + return buf; + } + + *len = (int)strlen(buf); +#ifdef _WIN32 + /* Strip '\r' off newlines. */ + if (*len > 1 && buf[*len - 2] == '\r' && buf[*len - 1] == '\n') + { + buf[*len - 2]= '\n'; + buf[*len - 1]= 0; + (*len)--; + } +#endif + return buf; +} + +/* + Wrapper for popen(). + On Windows, uses binary mode to workaround + C runtime bug mentioned in MDEV-9409 +*/ +static FILE* my_popen(const char *cmd, const char *mode) +{ + FILE *f= popen(cmd, mode); +#ifdef _WIN32 + if (f) + _setmode(fileno(f), O_BINARY); +#endif + return f; +} + #ifdef EMBEDDED_LIBRARY #define EMB_SEND_QUERY 1 @@ -1029,7 +1082,7 @@ static void init_connection_thd(struct st_connection *cn) cn->has_thread=TRUE; } -#else /*EMBEDDED_LIBRARY*/ +#else /* ! EMBEDDED_LIBRARY*/ #define init_connection_thd(X) do { } while(0) #define do_send_query(cn,q,q_len) mysql_send_query(cn->mysql, q, q_len) @@ -1044,8 +1097,8 @@ void do_eval(DYNAMIC_STRING *query_eval, const char *query, const char *query_end, my_bool pass_through_escape_chars) { const char *p; - register char c, next_c; - register int escaped = 0; + char c, next_c; + int escaped = 0; VAR *v; DBUG_ENTER("do_eval"); @@ -1095,9 +1148,7 @@ void do_eval(DYNAMIC_STRING *query_eval, const char *query, break; } } -#ifdef __WIN__ - fix_win_paths(query_eval->str, query_eval->length); -#endif + fix_win_paths(query_eval->str, query_eval->length); DBUG_VOID_RETURN; } @@ -1480,7 +1531,7 @@ void free_used_memory() free_defaults(default_argv); free_root(&require_file_root, MYF(0)); free_re(); -#ifdef __WIN__ +#ifdef _WIN32 free_tmp_sh_file(); free_win_path_patterns(); #endif @@ -1784,19 +1835,20 @@ static int run_command(char* cmd, DBUG_ENTER("run_command"); DBUG_PRINT("enter", ("cmd: %s", cmd)); - if (!(res_file= popen(cmd, "r"))) + if (!(res_file= my_popen(cmd, "r"))) { report_or_die("popen(\"%s\", \"r\") failed", cmd); DBUG_RETURN(-1); } - while (fgets(buf, sizeof(buf), res_file)) + int len; + while (my_fgets(buf, sizeof(buf), res_file, &len)) { DBUG_PRINT("info", ("buf: %s", buf)); if(ds_res) { /* Save the output of this command in the supplied string */ - dynstr_append(ds_res, buf); + dynstr_append_mem(ds_res, buf,len); } else { @@ -1852,7 +1904,7 @@ static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...) va_end(args); -#ifdef __WIN__ +#ifdef _WIN32 dynstr_append(&ds_cmdline, "\""); #endif @@ -1875,7 +1927,7 @@ static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...) not present. */ -#ifdef __WIN__ +#ifdef _WIN32 static int diff_check(const char *diff_name) { @@ -1885,14 +1937,15 @@ static int diff_check(const char *diff_name) my_snprintf(buf, sizeof(buf), "%s -v", diff_name); - if (!(res_file= popen(buf, "r"))) + if (!(res_file= my_popen(buf, "r"))) die("popen(\"%s\", \"r\") failed", buf); /* if diff is not present, nothing will be in stdout to increment have_diff */ - if (fgets(buf, sizeof(buf), res_file)) + int len; + if (my_fgets(buf, sizeof(buf), res_file, &len)) have_diff= 1; pclose(res_file); @@ -1932,7 +1985,7 @@ void show_diff(DYNAMIC_STRING* ds, in order to correctly detect non-availibility of 'diff', and the way it's implemented does not work with default 'diff' on Solaris. */ -#ifdef __WIN__ +#ifdef _WIN32 if (diff_check("diff")) diff_name = "diff"; else if (diff_check("mtrdiff")) @@ -1995,7 +2048,7 @@ void show_diff(DYNAMIC_STRING* ds, "two files was shown for you to diff manually.\n\n" "To get a better report you should install 'diff' on your system, which you\n" "for example can get from http://www.gnu.org/software/diffutils/diffutils.html\n" -#ifdef __WIN__ +#ifdef _WIN32 "or http://gnuwin32.sourceforge.net/packages/diffutils.htm\n" #endif "\n"); @@ -2341,7 +2394,7 @@ C_MODE_START static uchar *get_var_key(const uchar* var, size_t *len, my_bool __attribute__((unused)) t) { - register char* key; + char* key; key = ((VAR*)var)->name; *len = ((VAR*)var)->name_len; return (uchar*)key; @@ -2656,7 +2709,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end) DBUG_ASSERT(query_end); memset(&command, 0, sizeof(command)); command.query= (char*)query; - command.first_word_len= (*query_end - query); + command.first_word_len= (int)(*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 */ @@ -3060,7 +3113,7 @@ void open_file(const char *name) { char buff[FN_REFLEN]; size_t length; - const char *curname= cur_file->file_name; + char *curname= cur_file->file_name; DBUG_ENTER("open_file"); DBUG_PRINT("enter", ("name: %s", name)); @@ -3103,9 +3156,7 @@ void open_file(const char *name) 5.try in basedir */ -#ifdef __WIN__ fix_win_paths(curname, sizeof(curname)); -#endif bool in_overlay= opt_overlay_dir && !strncmp(curname, opt_overlay_dir, overlay_dir_len); @@ -3213,7 +3264,7 @@ void do_source(struct st_command *command) } -#if defined __WIN__ +#if defined _WIN32 #ifdef USE_CYGWIN /* Variables used for temporary sh files used for emulating Unix on Windows */ @@ -3240,21 +3291,9 @@ void free_tmp_sh_file() #endif -FILE* my_popen(DYNAMIC_STRING *ds_cmd, const char *mode) -{ -#if defined __WIN__ && defined USE_CYGWIN - /* Dump the command into a sh script file and execute with popen */ - str_to_file(tmp_sh_name, ds_cmd->str, ds_cmd->length); - return popen(tmp_sh_cmd, mode); -#else - return popen(ds_cmd->str, mode); -#endif -} - - static void init_builtin_echo(void) { -#ifdef __WIN__ +#ifdef _WIN32 size_t echo_length; /* Look for "echo.exe" in same dir as mysqltest was started from */ @@ -3366,7 +3405,7 @@ void do_exec(struct st_command *command) replace(&ds_cmd, "echo", 4, builtin_echo, strlen(builtin_echo)); } -#ifdef __WIN__ +#ifdef _WIN32 #ifndef USE_CYGWIN /* Replace /dev/null with NUL */ while(replace(&ds_cmd, "/dev/null", 9, "NUL", 3) == 0) @@ -3386,7 +3425,7 @@ void do_exec(struct st_command *command) DBUG_PRINT("info", ("Executing '%s' as '%s'", command->first_argument, ds_cmd.str)); - if (!(res_file= my_popen(&ds_cmd, "r"))) + if (!(res_file= my_popen(ds_cmd.str, "r"))) { dynstr_free(&ds_cmd); if (command->abort_on_error) @@ -3400,24 +3439,9 @@ void do_exec(struct st_command *command) init_dynamic_string(&ds_sorted, "", 1024, 1024); ds_result= &ds_sorted; } - -#ifdef _WIN32 - /* Workaround for CRT bug, MDEV-9409 */ - _setmode(fileno(res_file), O_BINARY); -#endif - - while (fgets(buf, sizeof(buf), res_file)) + int len; + while (my_fgets(buf, sizeof(buf), res_file,&len)) { - int len = (int)strlen(buf); -#ifdef _WIN32 - /* Strip '\r' off newlines. */ - if (len > 1 && buf[len-2] == '\r' && buf[len-1] == '\n') - { - buf[len-2] = '\n'; - buf[len-1] = 0; - len--; - } -#endif replace_dynstr_append_mem(ds_result, buf, len); } error= pclose(res_file); @@ -3548,7 +3572,7 @@ int do_modify_var(struct st_command *command, int my_system(DYNAMIC_STRING* ds_cmd) { -#if defined __WIN__ && defined USE_CYGWIN +#if defined _WIN32 && defined USE_CYGWIN /* Dump the command into a sh script file and execute with system */ str_to_file(tmp_sh_name, ds_cmd->str, ds_cmd->length); return system(tmp_sh_cmd); @@ -3587,7 +3611,7 @@ void do_system(struct st_command *command) /* Eval the system command, thus replacing all environment variables */ do_eval(&ds_cmd, command->first_argument, command->end, !is_windows); -#ifdef __WIN__ +#ifdef _WIN32 #ifndef USE_CYGWIN /* Replace /dev/null with NUL */ while(replace(&ds_cmd, "/dev/null", 9, "NUL", 3) == 0) @@ -4679,7 +4703,7 @@ void do_perl(struct st_command *command) /* Format the "perl <filename>" command */ my_snprintf(buf, sizeof(buf), "perl %s", temp_file_path); - if (!(res_file= popen(buf, "r"))) + if (!(res_file= my_popen(buf, "r"))) { if (command->abort_on_error) die("popen(\"%s\", \"r\") failed", buf); @@ -4687,16 +4711,17 @@ void do_perl(struct st_command *command) DBUG_VOID_RETURN; } - while (fgets(buf, sizeof(buf), res_file)) + int len; + while (my_fgets(buf, sizeof(buf), res_file,&len)) { if (disable_result_log) { - buf[strlen(buf)-1]=0; - DBUG_PRINT("exec_result",("%s", buf)); + buf[len - 1] = 0; + DBUG_PRINT("exec_result", ("%s", buf)); } else { - replace_dynstr_append(&ds_res, buf); + replace_dynstr_append_mem(&ds_res, buf, len); } } error= pclose(res_file); @@ -4707,7 +4732,7 @@ void do_perl(struct st_command *command) /* Check for error code that indicates perl could not be started */ int exstat= WEXITSTATUS(error); -#ifdef __WIN__ +#ifdef _WIN32 if (exstat == 1) /* Text must begin 'perl not found' as mtr looks for it */ abort_not_supported_test("perl not found in path or did not start"); @@ -4866,7 +4891,7 @@ void do_sync_with_master(struct st_command *command) char *p= command->first_argument; const char *offset_start= p; char *start, *buff= 0; - start= (char*) ""; + start= const_cast<char*>(""); if (*offset_start) { @@ -5116,7 +5141,7 @@ int query_get_string(MYSQL* mysql, const char* query, static int my_kill(int pid, int sig) { -#ifdef __WIN__ +#ifdef _WIN32 HANDLE proc; if ((proc= OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, pid)) == NULL) return -1; @@ -5190,8 +5215,7 @@ void do_shutdown_server(struct st_command *command) die("Failed to open file '%s'", ds_pidfile_name.str); dynstr_free(&ds_pidfile_name); - if (my_read(fd, (uchar*)&buff, - sizeof(buff), MYF(0)) <= 0){ + if (my_read(fd, (uchar*)&buff, sizeof(buff), MYF(0)) <= 0){ my_close(fd, MYF(0)); die("pid file was empty"); } @@ -5282,6 +5306,7 @@ uint get_errcode_from_name(const char *error_name, const char *error_end) handler_error_names))) return tmp; die("Unknown SQL error name '%s'", error_name); + return 0; // Keep compiler happy } const char *unknown_error= "<Unknown>"; @@ -5546,18 +5571,6 @@ static char *get_string(char **to_ptr, char **from_ptr, } -void set_reconnect(MYSQL* mysql, my_bool val) -{ - my_bool reconnect= val; - DBUG_ENTER("set_reconnect"); - DBUG_PRINT("info", ("val: %d", (int) val)); -#if MYSQL_VERSION_ID < 50000 - mysql->reconnect= reconnect; -#else - mysql_options(mysql, MYSQL_OPT_RECONNECT, (char *)&reconnect); -#endif - DBUG_VOID_RETURN; -} /** @@ -5642,11 +5655,7 @@ void do_close_connection(struct st_command *command) #ifndef EMBEDDED_LIBRARY if (command->type == Q_DIRTY_CLOSE) { - if (con->mysql->net.vio) - { - vio_delete(con->mysql->net.vio); - con->mysql->net.vio = 0; - } + mariadb_cancel(con->mysql); } #endif /*!EMBEDDED_LIBRARY*/ if (con->stmt) @@ -6104,7 +6113,7 @@ void do_connect(struct st_command *command) if (con_pipe) { -#ifdef __WIN__ +#ifdef _WIN32 opt_protocol= MYSQL_PROTOCOL_PIPE; #endif } @@ -6494,7 +6503,7 @@ void do_delimiter(struct st_command* command) if (!(*p)) die("Can't set empty delimiter"); - delimiter_length= strmake_buf(delimiter, p) - delimiter; + delimiter_length= (uint)(strmake_buf(delimiter, p) - delimiter); DBUG_PRINT("exit", ("delimiter: %s", delimiter)); command->last_argument= p + delimiter_length; @@ -6502,6 +6511,34 @@ void do_delimiter(struct st_command* command) } +/* + do_reset_connection + + DESCRIPTION + Reset the current session. +*/ + +static void do_reset_connection() +{ +#ifndef EMBEDDED_LIBRARY + MYSQL *mysql = cur_con->mysql; + + DBUG_ENTER("do_reset_connection"); + if (mysql_reset_connection(mysql)) + die("reset connection failed: %s", mysql_error(mysql)); + if (cur_con->stmt) + { + mysql_stmt_close(cur_con->stmt); + cur_con->stmt= NULL; + } + DBUG_VOID_RETURN; +#else + die("reset connection failed: unsupported by embedded server client library"); + return; +#endif +} + + my_bool match_delimiter(int c, const char *delim, uint length) { uint i; @@ -6734,40 +6771,38 @@ int read_line(char *buf, int size) if (!skip_char) { - /* Could be a multibyte character */ - /* This code is based on the code in "sql_load.cc" */ -#ifdef USE_MB - int charlen = my_mbcharlen(charset_info, (unsigned char) c); - /* We give up if multibyte character is started but not */ - /* completed before we pass buf_end */ - if ((charlen > 1) && (p + charlen) <= buf_end) + *p++= c; + if (use_mb(charset_info)) { - int i; - char* mb_start = p; - - *p++ = c; - - for (i= 1; i < charlen; i++) - { - c= my_getc(cur_file->file); - if (feof(cur_file->file)) - goto found_eof; - *p++ = c; - } - if (! my_ismbchar(charset_info, mb_start, p)) - { - /* It was not a multiline char, push back the characters */ - /* We leave first 'c', i.e. pretend it was a normal char */ - while (p-1 > mb_start) - my_ungetc(*--p); - } + const char *mb_start= p - 1; + /* Could be a multibyte character */ + /* See a similar code in "sql_load.cc" */ + for ( ; p < buf_end; ) + { + int charlen= my_charlen(charset_info, mb_start, p); + if (charlen > 0) + break; /* Full character */ + if (MY_CS_IS_TOOSMALL(charlen)) + { + /* We give up if multibyte character is started but not */ + /* completed before we pass buf_end */ + c= my_getc(cur_file->file); + if (feof(cur_file->file)) + goto found_eof; + *p++ = c; + continue; + } + DBUG_ASSERT(charlen == MY_CS_ILSEQ); + /* It was not a multiline char, push back the characters */ + /* We leave first 'c', i.e. pretend it was a normal char */ + while (p - 1 > mb_start) + my_ungetc(*--p); + break; + } } - else -#endif - *p++= c; } } - die("The input buffer is too small for this query.x\n" \ + die("The input buffer is too small for this query.\n" "check your query or increase MAX_QUERY and recompile"); DBUG_RETURN(0); } @@ -6924,13 +6959,13 @@ int read_command(struct st_command** command_ptr) if (parser.current_line < parser.read_lines) { - get_dynamic(&q_lines, (uchar*) command_ptr, parser.current_line) ; + get_dynamic(&q_lines, command_ptr, parser.current_line) ; DBUG_RETURN(0); } if (!(*command_ptr= command= (struct st_command*) my_malloc(sizeof(*command), MYF(MY_WME|MY_ZEROFILL))) || - insert_dynamic(&q_lines, (uchar*) &command)) + insert_dynamic(&q_lines, &command)) die("Out of memory"); command->type= Q_UNKNOWN; @@ -6982,7 +7017,7 @@ int read_command(struct st_command** command_ptr) command->first_argument= p; command->end= strend(command->query); - command->query_len= (command->end - command->query); + command->query_len= (int)(command->end - command->query); parser.read_lines++; DBUG_RETURN(0); } @@ -7170,7 +7205,7 @@ void read_embedded_server_arguments(const char *name) if (!embedded_server_arg_count) { embedded_server_arg_count=1; - embedded_server_args[0]= (char*) ""; /* Progname */ + embedded_server_args[0]= const_cast<char*>(""); /* Progname */ } if (!(file=my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME)))) die("Failed to open file '%s'", buff); @@ -7180,7 +7215,7 @@ void read_embedded_server_arguments(const char *name) { *(strend(str)-1)=0; /* Remove end newline */ if (!(embedded_server_args[embedded_server_arg_count]= - (char*) my_strdup(str,MYF(MY_WME)))) + my_strdup(str, MYF(MY_WME)))) { my_fclose(file,MYF(0)); die("Out of memory"); @@ -7242,7 +7277,7 @@ get_one_option(int optid, const struct my_option *opt, char *argument) } case 'p': if (argument == disabled_my_option) - argument= (char*) ""; // Don't require password + argument= const_cast<char*>(""); // Don't require password if (argument) { my_free(opt_pass); @@ -7261,7 +7296,7 @@ get_one_option(int optid, const struct my_option *opt, char *argument) if (!embedded_server_arg_count) { embedded_server_arg_count=1; - embedded_server_args[0]= (char*) ""; + embedded_server_args[0]= const_cast<char*>(""); } if (embedded_server_arg_count == MAX_EMBEDDED_SERVER_ARGS-1 || !(embedded_server_args[embedded_server_arg_count++]= @@ -7410,7 +7445,7 @@ void check_regerr(regex_t* r, int err) } -#ifdef __WIN__ +#ifdef _WIN32 DYNAMIC_ARRAY patterns; @@ -7460,7 +7495,7 @@ void init_win_path_patterns() continue; } - if (insert_dynamic(&patterns, (uchar*) &p)) + if (insert_dynamic(&patterns, &p)) die("Out of memory"); DBUG_PRINT("info", ("p: %s", p)); @@ -7484,6 +7519,7 @@ void free_win_path_patterns() } delete_dynamic(&patterns); } +#endif /* fix_win_paths @@ -7499,8 +7535,9 @@ void free_win_path_patterns() => all \ from c:\mysql\m... until next space is converted into / */ -void fix_win_paths(const char *val, size_t len) +void fix_win_paths(char *val, size_t len) { +#ifdef _WIN32 uint i; char *p; @@ -7511,7 +7548,7 @@ void fix_win_paths(const char *val, size_t len) DBUG_PRINT("info", ("pattern: %s", *pattern)); /* Search for the path in string */ - while ((p= strstr((char*)val, *pattern))) + while ((p= strstr(val, *pattern))) { DBUG_PRINT("info", ("Found %s in val p: %s", *pattern, p)); @@ -7524,10 +7561,10 @@ void fix_win_paths(const char *val, size_t len) DBUG_PRINT("info", ("Converted \\ to /, p: %s", p)); } } - DBUG_PRINT("exit", (" val: %s, len: %d", val, len)); + DBUG_PRINT("exit", (" val: %s, len: %zu", val, len)); DBUG_VOID_RETURN; -} #endif +} @@ -7536,7 +7573,7 @@ void fix_win_paths(const char *val, size_t len) */ void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field, - char* val, ulonglong len, my_bool is_null) + char* val, size_t len, my_bool is_null) { char null[]= "NULL"; @@ -7550,7 +7587,7 @@ void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field, val= null; len= 4; } -#ifdef __WIN__ +#ifdef _WIN32 else if ((field->type == MYSQL_TYPE_DOUBLE || field->type == MYSQL_TYPE_FLOAT ) && field->decimals >= 31) @@ -7581,13 +7618,13 @@ void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field, { if (col_idx) dynstr_append_mem(ds, "\t", 1); - replace_dynstr_append_mem(ds, val, (int)len); + replace_dynstr_append_mem(ds, val, len); } else { dynstr_append(ds, field->name); dynstr_append_mem(ds, "\t", 1); - replace_dynstr_append_mem(ds, val, (int)len); + replace_dynstr_append_mem(ds, val, len); dynstr_append_mem(ds, "\n", 1); } } @@ -7725,8 +7762,7 @@ void append_metadata(DYNAMIC_STRING *ds, dynstr_append_mem(ds, "\t", 1); replace_dynstr_append_uint(ds, field->max_length); dynstr_append_mem(ds, "\t", 1); - dynstr_append_mem(ds, (char*) (IS_NOT_NULL(field->flags) ? - "N" : "Y"), 1); + dynstr_append_mem(ds, (IS_NOT_NULL(field->flags) ? "N" : "Y"), 1); dynstr_append_mem(ds, "\t", 1); replace_dynstr_append_uint(ds, field->flags); dynstr_append_mem(ds, "\t", 1); @@ -7757,6 +7793,70 @@ void append_info(DYNAMIC_STRING *ds, ulonglong affected_rows, } +/** + @brief Append state change information (received through Ok packet) to the output. + + @param [in,out] ds Dynamic string to hold the content to be printed. + @param [in] mysql Connection handle. +*/ + +static void append_session_track_info(DYNAMIC_STRING *ds, MYSQL *mysql) +{ +#ifndef EMBEDDED_LIBRARY + for (unsigned int type= SESSION_TRACK_BEGIN; type <= SESSION_TRACK_END; type++) + { + const char *data; + size_t data_length; + + if (!mysql_session_track_get_first(mysql, + (enum_session_state_type) type, + &data, &data_length)) + { + dynstr_append(ds, "-- "); + switch (type) + { + case SESSION_TRACK_SYSTEM_VARIABLES: + dynstr_append(ds, "Tracker : SESSION_TRACK_SYSTEM_VARIABLES\n"); + break; + case SESSION_TRACK_SCHEMA: + dynstr_append(ds, "Tracker : SESSION_TRACK_SCHEMA\n"); + break; + case SESSION_TRACK_STATE_CHANGE: + dynstr_append(ds, "Tracker : SESSION_TRACK_STATE_CHANGE\n"); + break; + case SESSION_TRACK_GTIDS: + dynstr_append(ds, "Tracker : SESSION_TRACK_GTIDS\n"); + break; + case SESSION_TRACK_TRANSACTION_CHARACTERISTICS: + dynstr_append(ds, "Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS\n"); + break; + case SESSION_TRACK_TRANSACTION_TYPE: + dynstr_append(ds, "Tracker : SESSION_TRACK_TRANSACTION_TYPE\n"); + break; + default: + DBUG_ASSERT(0); + dynstr_append(ds, "\n"); + } + + + dynstr_append(ds, "-- "); + dynstr_append_mem(ds, data, data_length); + } + else + continue; + while (!mysql_session_track_get_next(mysql, + (enum_session_state_type) type, + &data, &data_length)) + { + dynstr_append(ds, "\n-- "); + dynstr_append_mem(ds, data, data_length); + } + dynstr_append(ds, "\n\n"); + } +#endif /* EMBEDDED_LIBRARY */ +} + + /* Display the table headings with the names tab separated */ @@ -7937,6 +8037,9 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, if (!disable_info) append_info(ds, mysql_affected_rows(mysql), mysql_info(mysql)); + if (display_session_track_info) + append_session_track_info(ds, mysql); + /* Add all warnings to the result. We can't do this if we are in the middle of processing results from multi-statement, because @@ -8352,6 +8455,10 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, if (!disable_info) append_info(ds, mysql_stmt_affected_rows(stmt), mysql_info(mysql)); + if (display_session_track_info) + append_session_track_info(ds, mysql); + + if (!disable_warnings) { /* Get the warnings from execute */ @@ -8394,10 +8501,18 @@ end: revert_properties(); /* Close the statement if reconnect, need new prepare */ - if (mysql->reconnect) { - mysql_stmt_close(stmt); - cn->stmt= NULL; +#ifndef EMBEDDED_LIBRARY + my_bool reconnect; + mysql_get_option(mysql, MYSQL_OPT_RECONNECT, &reconnect); + if (reconnect) +#else + if (mysql->reconnect) +#endif + { + mysql_stmt_close(stmt); + cn->stmt= NULL; + } } DBUG_VOID_RETURN; @@ -8525,7 +8640,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) if (flags & QUERY_PRINT_ORIGINAL_FLAG) { print_query= command->query; - print_len= command->end - command->query; + print_len= (int)(command->end - command->query); } replace_dynstr_append_mem(ds, print_query, print_len); dynstr_append_mem(ds, delimiter, delimiter_length); @@ -8577,7 +8692,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) Yes, it was possible to create this query as a view */ view_created= 1; - query= (char*)"SELECT * FROM mysqltest_tmp_v"; + query= const_cast<char*>("SELECT * FROM mysqltest_tmp_v"); query_len = strlen(query); /* @@ -8624,7 +8739,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) { sp_created= 1; - query= (char*)"CALL mysqltest_tmp_sp()"; + query= const_cast<char*>("CALL mysqltest_tmp_sp()"); query_len = strlen(query); } dynstr_free(&query_str); @@ -8930,7 +9045,7 @@ static void dump_backtrace(void) #endif } fputs("Attempting backtrace...\n", stderr); - my_print_stacktrace(NULL, my_thread_stack_size); + my_print_stacktrace(NULL, (ulong)my_thread_stack_size); } #else @@ -8950,12 +9065,12 @@ static sig_handler signal_handler(int sig) fprintf(stderr, "Writing a core file...\n"); fflush(stderr); my_write_core(sig); -#ifndef __WIN__ +#ifndef _WIN32 exit(1); // Shouldn't get here but just in case #endif } -#ifdef __WIN__ +#ifdef _WIN32 LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp) { @@ -8992,7 +9107,7 @@ static void init_signal_handling(void) SetUnhandledExceptionFilter(exception_filter); } -#else /* __WIN__ */ +#else /* _WIN32 */ static void init_signal_handling(void) { @@ -9019,7 +9134,7 @@ static void init_signal_handling(void) DBUG_VOID_RETURN; } -#endif /* !__WIN__ */ +#endif /* !_WIN32 */ int main(int argc, char **argv) { @@ -9087,7 +9202,7 @@ int main(int argc, char **argv) memset(&var_reg, 0, sizeof(var_reg)); init_builtin_echo(); -#ifdef __WIN__ +#ifdef _WIN32 #ifndef USE_CYGWIN is_windows= 1; #endif @@ -9225,7 +9340,7 @@ int main(int argc, char **argv) } verbose_msg("Start processing test commands from '%s' ...", cur_file->file_name); - while (!read_command(&command) && !abort_flag) + while (!abort_flag && !read_command(&command)) { my_bool ok_to_do; int current_line_inc = 1, processed = 0; @@ -9325,6 +9440,12 @@ int main(int argc, char **argv) case Q_DISABLE_INFO: set_property(command, P_INFO, 1); break; + case Q_ENABLE_SESSION_TRACK_INFO: + set_property(command, P_SESSION_TRACK, 1); + break; + case Q_DISABLE_SESSION_TRACK_INFO: + set_property(command, P_SESSION_TRACK, 0); + break; case Q_ENABLE_METADATA: set_property(command, P_META, 1); break; @@ -9535,6 +9656,9 @@ int main(int argc, char **argv) case Q_PING: handle_command_error(command, mysql_ping(cur_con->mysql), -1); break; + case Q_RESET_CONNECTION: + do_reset_connection(); + break; case Q_SEND_SHUTDOWN: handle_command_error(command, mysql_shutdown(cur_con->mysql, @@ -9573,10 +9697,10 @@ int main(int argc, char **argv) non_blocking_api_enabled= 1; break; case Q_DISABLE_RECONNECT: - set_reconnect(cur_con->mysql, 0); + mysql_options(cur_con->mysql, MYSQL_OPT_RECONNECT, &my_false); break; case Q_ENABLE_RECONNECT: - set_reconnect(cur_con->mysql, 1); + mysql_options(cur_con->mysql, MYSQL_OPT_RECONNECT, &my_true); /* Close any open statements - no reconnect, need new prepare */ close_statements(); break; @@ -9610,11 +9734,9 @@ int main(int argc, char **argv) do_eval(&ds_res, command->first_argument, command->end, FALSE); abort_not_supported_test("%s",ds_res.str); break; - case Q_RESULT: die("result, deprecated command"); break; - default: processed= 0; break; @@ -9843,7 +9965,7 @@ typedef struct st_pointer_array { /* when using array-strings */ struct st_replace *init_replace(char * *from, char * *to, uint count, char * word_end_chars); -int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name); +int insert_pointer_name(POINTER_ARRAY *pa,char * name); void free_pointer_array(POINTER_ARRAY *pa); /* @@ -9865,8 +9987,8 @@ void do_get_replace(struct st_command *command) free_replace(); - bzero((char*) &to_array,sizeof(to_array)); - bzero((char*) &from_array,sizeof(from_array)); + bzero(&to_array,sizeof(to_array)); + bzero(&from_array,sizeof(from_array)); if (!*from) die("Missing argument in %s", command->query); start= buff= (char*)my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE)); @@ -9877,9 +9999,7 @@ void do_get_replace(struct st_command *command) if (!*from) die("Wrong number of arguments to replace_result in '%s'", command->query); -#ifdef __WIN__ fix_win_paths(to, from - to); -#endif insert_pointer_name(&from_array,to); to= get_string(&buff, &from, command); insert_pointer_name(&to_array,to); @@ -9927,8 +10047,8 @@ void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds, const char *str, int len __attribute__((unused))) { - reg1 REPLACE *rep_pos; - reg2 REPLACE_STRING *rep_str; + REPLACE *rep_pos; + REPLACE_STRING *rep_str; const char *start, *from; DBUG_ENTER("replace_strings_append"); @@ -10114,7 +10234,7 @@ void append_replace_regex(char* expr, char *expr_end, struct st_replace_regex* r } /* done parsing the statement, now place it in regex_arr */ - if (insert_dynamic(&res->regex_arr,(uchar*) ®)) + if (insert_dynamic(&res->regex_arr, ®)) die("Out of memory"); } @@ -10161,7 +10281,7 @@ int multi_reg_replace(struct st_replace_regex* r,char* val) struct st_regex re; char* save_out_buf= out_buf; - get_dynamic(&r->regex_arr,(uchar*)&re,i); + get_dynamic(&r->regex_arr, &re, i); if (!reg_replace(&out_buf, buf_len_p, re.pattern, re.replace, in_buf, re.icase)) @@ -10227,7 +10347,7 @@ void free_replace_regex() */ #define SECURE_REG_BUF if (buf_len < need_buf_len) \ { \ - int off= res_p - buf; \ + ssize_t off= res_p - buf; \ buf= (char*)my_realloc(buf,need_buf_len,MYF(MY_WME+MY_FAE)); \ res_p= buf + off; \ buf_len= need_buf_len; \ @@ -10252,13 +10372,15 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern, regmatch_t *subs; char *replace_end; char *buf= *buf_p; - int len; - int buf_len, need_buf_len; + size_t len; + size_t buf_len, need_buf_len; int cflags= REG_EXTENDED | REG_DOTALL; int err_code; char *res_p,*str_p,*str_end; - buf_len= *buf_len_p; + DBUG_ASSERT(*buf_len_p > 0); + + buf_len= (size_t)*buf_len_p; len= strlen(string); str_end= string + len; @@ -10401,7 +10523,7 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern, } else /* no match this time, just copy the string as is */ { - int left_in_str= str_end-str_p; + size_t left_in_str= str_end-str_p; need_buf_len= (res_p-buf) + left_in_str; SECURE_REG_BUF memcpy(res_p,str_p,left_in_str); @@ -10520,7 +10642,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count, if (len > max_length) max_length=len; } - bzero((char*) is_word_end,sizeof(is_word_end)); + bzero(is_word_end, sizeof(is_word_end)); for (i=0 ; word_end_chars[i] ; i++) is_word_end[(uchar) word_end_chars[i]]=1; @@ -10611,7 +10733,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count, or_bits(sets.set+used_sets,sets.set); /* Can restart from start */ /* Find all chars that follows current sets */ - bzero((char*) used_chars,sizeof(used_chars)); + bzero(used_chars, sizeof(used_chars)); for (i= (uint) ~0; (i=get_next_bit(sets.set+used_sets,i)) ;) { used_chars[follow[i].chr]=1; @@ -10745,7 +10867,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count, int init_sets(REP_SETS *sets,uint states) { - bzero((char*) sets,sizeof(*sets)); + bzero(sets, sizeof(*sets)); sets->size_of_bits=((states+7)/8); if (!(sets->set_buffer=(REP_SET*) my_malloc(sizeof(REP_SET)*SET_MALLOC_HUNC, MYF(MY_WME)))) @@ -10776,8 +10898,8 @@ REP_SET *make_new_set(REP_SETS *sets) { sets->extra--; set=sets->set+ sets->count++; - bzero((char*) set->bits,sizeof(uint)*sets->size_of_bits); - bzero((char*) &set->next[0],sizeof(set->next[0])*LAST_CHAR_CODE); + bzero(set->bits, sizeof(uint) * sets->size_of_bits); + bzero(&set->next[0], sizeof(set->next[0]) * LAST_CHAR_CODE); set->found_offset=0; set->found_len=0; set->table_offset= (uint) ~0; @@ -10785,13 +10907,12 @@ REP_SET *make_new_set(REP_SETS *sets) return set; } count=sets->count+sets->invisible+SET_MALLOC_HUNC; - if (!(set=(REP_SET*) my_realloc((uchar*) sets->set_buffer, - sizeof(REP_SET)*count, + if (!(set=(REP_SET*) my_realloc(sets->set_buffer, sizeof(REP_SET)*count, MYF(MY_WME)))) return 0; sets->set_buffer=set; sets->set=set+sets->invisible; - if (!(bit_buffer=(uint*) my_realloc((uchar*) sets->bit_buffer, + if (!(bit_buffer=(uint*) my_realloc(sets->bit_buffer, (sizeof(uint)*sets->size_of_bits)*count, MYF(MY_WME)))) return 0; @@ -10834,7 +10955,7 @@ void internal_clear_bit(REP_SET *set, uint bit) void or_bits(REP_SET *to,REP_SET *from) { - reg1 uint i; + uint i; for (i=0 ; i < to->size_of_bits ; i++) to->bits[i]|=from->bits[i]; return; @@ -10842,7 +10963,7 @@ void or_bits(REP_SET *to,REP_SET *from) void copy_bits(REP_SET *to,REP_SET *from) { - memcpy((uchar*) to->bits,(uchar*) from->bits, + memcpy(to->bits, from->bits, (size_t) (sizeof(uint) * to->size_of_bits)); } @@ -10936,7 +11057,7 @@ uint end_of_word(char * pos) #define PC_MALLOC 256 /* Bytes for pointers */ #define PS_MALLOC 512 /* Bytes for data */ -int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name) +int insert_pointer_name(POINTER_ARRAY *pa,char * name) { uint i,length,old_count; uchar *new_pos; @@ -10950,8 +11071,8 @@ int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name) (sizeof(char *)+sizeof(*pa->flag))* (sizeof(char *)+sizeof(*pa->flag))),MYF(MY_WME)))) DBUG_RETURN(-1); - if (!(pa->str= (uchar*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD), - MYF(MY_WME)))) + if (!(pa->str= (uchar*) my_malloc(PS_MALLOC - MALLOC_OVERHEAD, + MYF(MY_WME)))) { my_free(pa->typelib.type_names); DBUG_RETURN (-1); @@ -10966,9 +11087,8 @@ int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name) length=(uint) strlen(name)+1; if (pa->length+length >= pa->max_length) { - if (!(new_pos= (uchar*) my_realloc((uchar*) pa->str, - (uint) (pa->length+length+PS_MALLOC), - MYF(MY_WME)))) + if (!(new_pos= (uchar*) my_realloc(pa->str, pa->length + length + PS_MALLOC, + MYF(MY_WME)))) DBUG_RETURN(1); if (new_pos != pa->str) { @@ -10985,8 +11105,8 @@ int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name) int len; pa->array_allocs++; len=(PC_MALLOC*pa->array_allocs - MALLOC_OVERHEAD); - if (!(new_array=(const char **) my_realloc((uchar*) pa->typelib.type_names, - (uint) len/ + if (!(new_array=(const char **) my_realloc(pa->typelib.type_names, + len/ (sizeof(uchar*)+sizeof(*pa->flag))* (sizeof(uchar*)+sizeof(*pa->flag)), MYF(MY_WME)))) @@ -10995,13 +11115,13 @@ int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name) old_count=pa->max_count; pa->max_count=len/(sizeof(uchar*) + sizeof(*pa->flag)); pa->flag= (uint8*) (pa->typelib.type_names+pa->max_count); - memcpy((uchar*) pa->flag,(char *) (pa->typelib.type_names+old_count), + memcpy(pa->flag, (pa->typelib.type_names +old_count), old_count*sizeof(*pa->flag)); } 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 */ @@ -11024,22 +11144,24 @@ void free_pointer_array(POINTER_ARRAY *pa) /* Functions that uses replace and replace_regex */ /* Append the string to ds, with optional replace */ -void replace_dynstr_append_mem(DYNAMIC_STRING *ds, - const char *val, size_t len) +void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, size_t len) { - char lower[512]; -#ifdef __WIN__ - fix_win_paths(val, len); -#endif + char lower[1024]; - if (display_result_lower) + if (len < sizeof(lower) - 1) { - /* Convert to lower case, and do this first */ - char *c= lower; - for (const char *v= val; *v; v++) - *c++= my_tolower(charset_info, *v); - *c= '\0'; - /* Copy from this buffer instead */ + if (display_result_lower) + { + /* Convert to lower case, and do this first */ + char *c= lower; + for (const char *v= val; *v; v++) + *c++= my_tolower(charset_info, *v); + *c= '\0'; + /* Copy from this buffer instead */ + } + else + memcpy(lower, val, len+1); + fix_win_paths(lower, len); val= lower; } @@ -11128,7 +11250,7 @@ void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input, *line_end= 0; /* Insert pointer to the line in array */ - if (insert_dynamic(&lines, (uchar*) &start)) + if (insert_dynamic(&lines, &start)) die("Out of memory inserting lines to sort"); start= line_end+1; |