summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--[-rwxr-xr-x]client/CMakeLists.txt10
-rw-r--r--client/Makefile.am101
-rw-r--r--client/client_priv.h31
-rw-r--r--client/get_password.c4
-rw-r--r--client/mysql.cc219
-rw-r--r--client/mysqladmin.cc84
-rw-r--r--client/mysqlbinlog.cc164
-rw-r--r--client/mysqlcheck.c92
-rw-r--r--client/mysqldump.c493
-rw-r--r--client/mysqlimport.c253
-rw-r--r--client/mysqlmanager-pwgen.c160
-rw-r--r--client/mysqlmanagerc.c173
-rw-r--r--client/mysqlshow.c22
-rw-r--r--client/mysqlslap.c2104
-rw-r--r--client/mysqltest.c88
-rw-r--r--client/sql_string.h2
16 files changed, 3239 insertions, 761 deletions
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index 6e37d02ecd8..8ec8b0111b0 100755..100644
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -25,7 +25,6 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/extra/yassl/include
${CMAKE_SOURCE_DIR}/libmysql
${CMAKE_SOURCE_DIR}/regex
- ${CMAKE_SOURCE_DIR}/mysys
${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/strings)
@@ -83,20 +82,24 @@ ADD_EXECUTABLE(mysqlimport mysqlimport.c)
TARGET_LINK_LIBRARIES(mysqlimport mysqlclient mysys dbug yassl taocrypt zlib wsock32)
ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c ../mysys/my_getpagesize.c)
-TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient mysys dbug yassl taocrypt zlib wsock32)
+TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient dbug yassl taocrypt zlib wsock32)
ADD_DEPENDENCIES(mysql_upgrade GenFixPrivs)
ADD_EXECUTABLE(mysqlshow mysqlshow.c)
TARGET_LINK_LIBRARIES(mysqlshow mysqlclient mysys dbug yassl taocrypt zlib wsock32)
ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc ../mysys/mf_tempdir.c ../mysys/my_new.cc
- ../mysys/my_bit.c ../mysys/my_bitmap.c
+ ../mysys/my_bit.c ../mysys/my_bitmap.c ../mysys/my_vle.c
../mysys/base64.c)
TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient dbug yassl taocrypt zlib wsock32)
ADD_EXECUTABLE(mysqladmin mysqladmin.cc)
TARGET_LINK_LIBRARIES(mysqladmin mysqlclient mysys dbug yassl taocrypt zlib wsock32)
+ADD_EXECUTABLE(mysqlslap mysqlslap.c)
+SET_SOURCE_FILES_PROPERTIES(mysqlslap.c PROPERTIES COMPILE_FLAGS "-DTHREADS")
+TARGET_LINK_LIBRARIES(mysqlslap mysqlclient mysys yassl taocrypt zlib wsock32 dbug)
+
ADD_EXECUTABLE(echo echo.c)
IF(EMBED_MANIFESTS)
@@ -111,4 +114,3 @@ IF(EMBED_MANIFESTS)
MYSQL_EMBED_MANIFEST("mysqladmin" "asInvoker")
MYSQL_EMBED_MANIFEST("echo" "asInvoker")
ENDIF(EMBED_MANIFESTS)
-
diff --git a/client/Makefile.am b/client/Makefile.am
index c7663c7da82..2d8bd918734 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -1,64 +1,109 @@
# Copyright (C) 2000-2006 MySQL AB
-#
+#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# This file is public domain and comes with NO WARRANTY of any kind
-#AUTOMAKE_OPTIONS = nostdinc
+if THREAD_SAFE_CLIENT
+LIBMYSQLCLIENT_LA = $(top_builddir)/libmysql_r/libmysqlclient_r.la
+else
+LIBMYSQLCLIENT_LA = $(top_builddir)/libmysql/libmysqlclient.la
+endif
+
INCLUDES = -I$(top_builddir)/include \
-I$(top_srcdir)/include \
-I$(top_srcdir)/regex \
$(openssl_includes)
+
LIBS = @CLIENT_LIBS@
-LDADD= @CLIENT_EXTRA_LDFLAGS@ \
- $(top_builddir)/libmysql/libmysqlclient.la
-bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \
- mysqldump mysqlimport mysqltest mysqlbinlog \
- mysql_upgrade \
- mysqltestmanagerc mysqltestmanager-pwgen
+
+LDADD= @CLIENT_EXTRA_LDFLAGS@ $(CLIENT_THREAD_LIBS) \
+ $(top_builddir)/libmysql/libmysqlclient.la
+
noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \
client_priv.h
-mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc
+
+EXTRA_DIST = get_password.c CMakeLists.txt echo.c
+
+BUILT_SOURCES = link_sources
+
+CLEANFILES = $(BUILT_SOURCES)
+
+bin_PROGRAMS = mysql \
+ mysqladmin \
+ mysqlbinlog \
+ mysqlcheck \
+ mysqldump \
+ mysqlimport \
+ mysqlshow \
+ mysqlslap \
+ mysqltest \
+ mysql_upgrade
+
+mysql_SOURCES = mysql.cc readline.cc sql_string.cc \
+ completion_hash.cc
+mysql_LDADD = @readline_link@ @TERMCAP_LIB@ \
+ $(LDADD) $(CXXLDFLAGS)
mysqladmin_SOURCES = mysqladmin.cc
-mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS)
-mysqltest_SOURCES= mysqltest.c \
- $(top_srcdir)/mysys/my_getsystime.c \
- $(top_srcdir)/mysys/my_copy.c
-mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD)
-mysqlbinlog_SOURCES = mysqlbinlog.cc \
+mysqlbinlog_SOURCES = mysqlbinlog.cc \
$(top_srcdir)/mysys/mf_tempdir.c \
- $(top_srcdir)/mysys/my_new.cc
+ $(top_srcdir)/mysys/my_new.cc \
+ $(top_srcdir)/mysys/my_bit.c \
+ $(top_srcdir)/mysys/my_bitmap.c \
+ $(top_srcdir)/mysys/my_vle.c \
+ $(top_srcdir)/mysys/base64.c
mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS)
-mysqltestmanager_pwgen_SOURCES = mysqlmanager-pwgen.c
-mysqltestmanagerc_SOURCES= mysqlmanagerc.c
-mysqlcheck_SOURCES= mysqlcheck.c
-mysqlshow_SOURCES= mysqlshow.c
-mysqldump_SOURCES= mysqldump.c my_user.c \
+
+mysqldump_SOURCES= mysqldump.c \
+ my_user.c \
$(top_srcdir)/mysys/mf_getdate.c
-mysqlimport_SOURCES= mysqlimport.c
+
+mysqlimport_SOURCES= mysqlimport.c
+
+mysqlimport_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
+ @CLIENT_EXTRA_LDFLAGS@ \
+ $(LIBMYSQLCLIENT_LA) \
+ $(top_builddir)/mysys/libmysys.a
+
+mysqlshow_SOURCES= mysqlshow.c
+
+mysqlslap_SOURCES= mysqlslap.c
+mysqlslap_CFLAGS= -DTHREAD -UUNDEF_THREADS_HACK
+mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
+ @CLIENT_EXTRA_LDFLAGS@ \
+ $(LIBMYSQLCLIENT_LA) \
+ $(top_builddir)/mysys/libmysys.a
+
+mysqltest_SOURCES= mysqltest.c \
+ $(top_srcdir)/mysys/my_getsystime.c \
+ $(top_srcdir)/mysys/my_copy.c
+mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD)
+
mysql_upgrade_SOURCES= mysql_upgrade.c \
$(top_srcdir)/mysys/my_getpagesize.c
-sql_src=log_event.h mysql_priv.h log_event.cc my_decimal.h my_decimal.cc
-strings_src=decimal.c
# Fix for mit-threads
DEFS = -DUNDEF_THREADS_HACK \
-DDEFAULT_MYSQL_HOME="\"$(prefix)\"" \
-DDATADIR="\"$(localstatedir)\""
-EXTRA_DIST = get_password.c CMakeLists.txt echo.c
+sql_src=log_event.h mysql_priv.h rpl_constants.h \
+ 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
+strings_src=decimal.c
link_sources:
for f in $(sql_src) ; do \
@@ -71,7 +116,7 @@ link_sources:
done; \
rm -f $(srcdir)/my_user.c; \
@LN_CP_F@ $(top_srcdir)/sql-common/my_user.c my_user.c;
-
+ echo timestamp > link_sources;
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/client/client_priv.h b/client/client_priv.h
index 418bf86f2c8..25241cc8c59 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -23,7 +23,13 @@
#include <errmsg.h>
#include <my_getopt.h>
-/* We have to define 'enum options' identical in all files to keep OS2 happy */
+#ifndef WEXITSTATUS
+# ifdef __WIN__
+# define WEXITSTATUS(stat_val) (stat_val)
+# else
+# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+# endif
+#endif
enum options_client
{
@@ -49,7 +55,26 @@ enum options_client
OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING,
#endif
OPT_TRIGGERS,
+ OPT_MYSQL_ONLY_PRINT,
+ OPT_MYSQL_LOCK_DIRECTORY,
+ OPT_USE_THREADS,
+ OPT_IMPORT_USE_THREADS,
+ OPT_MYSQL_NUMBER_OF_QUERY,
+ OPT_MYSQL_PRESERVE_SCHEMA,
OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
- OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_SSL_VERIFY_SERVER_CERT,
- OPT_DEBUG_INFO, OPT_ERROR_LOG_FILE
+ OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_CREATE_SLAP_SCHEMA,
+ 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,
+ OPT_SLAP_AUTO_GENERATE_GUID_PRIMARY,
+ OPT_SLAP_AUTO_GENERATE_EXECUTE_QUERIES,
+ OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES,
+ OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM,
+ OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM,
+ OPT_SLAP_PRE_QUERY,
+ OPT_SLAP_POST_QUERY,
+ OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT, OPT_SERVER_ID,
+ OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT,
+ OPT_DEBUG_INFO, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE, OPT_WRITE_BINLOG,
+ OPT_MAX_CLIENT_OPTION
};
diff --git a/client/get_password.c b/client/get_password.c
index e7e6c850469..37761d5bb5d 100644
--- a/client/get_password.c
+++ b/client/get_password.c
@@ -63,7 +63,7 @@
/* were just going to fake it here and get input from
the keyboard */
-char *get_tty_password(char *opt_message)
+char *get_tty_password(const char *opt_message)
{
char to[80];
char *pos=to,*end=to+sizeof(to)-1;
@@ -149,7 +149,7 @@ static void get_password(char *to,uint length,int fd,bool echo)
#endif /* ! HAVE_GETPASS */
-char *get_tty_password(char *opt_message)
+char *get_tty_password(const char *opt_message)
{
#ifdef HAVE_GETPASS
char *passbuff;
diff --git a/client/mysql.cc b/client/mysql.cc
index 368fce30d67..31cb78de1fd 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -43,7 +43,7 @@
#include <locale.h>
#endif
-const char *VER= "14.12";
+const char *VER= "14.13";
/* Don't try to make a nice table if the data is too big */
#define MAX_COLUMN_LENGTH 1024
@@ -83,7 +83,7 @@ extern "C" {
#endif
#undef bcmp // Fix problem with new readline
-#if defined( __WIN__) || defined(OS2)
+#if defined( __WIN__)
#include <conio.h>
#elif !defined(__NETWARE__)
#include <readline/readline.h>
@@ -103,7 +103,7 @@ extern "C" {
#define cmp_database(cs,A,B) strcmp((A),(B))
#endif
-#if !defined( __WIN__) && !defined( OS2) && !defined(__NETWARE__) && (!defined(HAVE_mit_thread) || !defined(THREAD))
+#if !defined( __WIN__) && !defined(__NETWARE__) && !defined(THREAD)
#define USE_POPEN
#endif
@@ -138,8 +138,8 @@ static my_bool info_flag=0,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;
-static volatile int executing_query= 0, interrupted_query= 0;
+ show_warnings= 0, executing_query= 0, interrupted_query= 0;
+static my_bool column_types_flag;
static ulong opt_max_allowed_packet, opt_net_buffer_length;
static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0;
static my_string opt_mysql_unix_port=0;
@@ -342,8 +342,7 @@ static void end_timer(ulong start_time,char *buff);
static void mysql_end_timer(ulong start_time,char *buff);
static void nice_time(double sec,char *buff,bool part_second);
static sig_handler mysql_end(int sig);
-static sig_handler mysql_sigint(int sig);
-
+static sig_handler handle_sigint(int sig);
int main(int argc,char *argv[])
{
@@ -440,7 +439,7 @@ int main(int argc,char *argv[])
if (opt_sigint_ignore)
signal(SIGINT, SIG_IGN);
else
- signal(SIGINT, mysql_sigint); // Catch SIGINT to clean up
+ signal(SIGINT, handle_sigint); // Catch SIGINT to clean up
signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up
put_info("Welcome to the MySQL monitor. Commands end with ; or \\g.",
@@ -504,28 +503,6 @@ int main(int argc,char *argv[])
#endif
}
-sig_handler mysql_sigint(int sig)
-{
- char kill_buffer[40];
- MYSQL *kill_mysql= NULL;
-
- signal(SIGINT, mysql_sigint);
-
- /* terminate if no query being executed, or we already tried interrupting */
- if (!executing_query || interrupted_query++)
- mysql_end(sig);
-
- kill_mysql= mysql_init(kill_mysql);
- if (!mysql_real_connect(kill_mysql,current_host, current_user, opt_password,
- "", opt_mysql_port, opt_mysql_unix_port,0))
- mysql_end(sig);
- /* kill_buffer is always big enough because max length of %lu is 15 */
- sprintf(kill_buffer, "KILL /*!50000 QUERY */ %lu", mysql_thread_id(&mysql));
- mysql_real_query(kill_mysql, kill_buffer, strlen(kill_buffer));
- mysql_close(kill_mysql);
- tee_fprintf(stdout, "Query aborted by Ctrl+C\n");
-}
-
sig_handler mysql_end(int sig)
{
mysql_close(&mysql);
@@ -564,11 +541,40 @@ sig_handler mysql_end(int sig)
my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
mysql_server_end();
free_defaults(defaults_argv);
- my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
+ my_end(info_flag ? MY_CHECK_ERROR : 0);
exit(status.exit_status);
}
+/*
+ This function handles sigint calls
+ If query is in process, kill query
+ no query in process, terminate like previous behavior
+ */
+sig_handler handle_sigint(int sig)
+{
+ char kill_buffer[40];
+ MYSQL *kill_mysql= NULL;
+
+ /* terminate if no query being executed, or we already tried interrupting */
+ if (!executing_query || interrupted_query)
+ mysql_end(sig);
+
+ kill_mysql= mysql_init(kill_mysql);
+ if (!mysql_real_connect(kill_mysql,current_host, current_user, opt_password,
+ "", opt_mysql_port, opt_mysql_unix_port,0))
+ mysql_end(sig);
+
+ /* kill_buffer is always big enough because max length of %lu is 15 */
+ sprintf(kill_buffer, "KILL /*!50000 QUERY */ %lu", mysql_thread_id(&mysql));
+ mysql_real_query(kill_mysql, kill_buffer, strlen(kill_buffer));
+ mysql_close(kill_mysql);
+ tee_fprintf(stdout, "Query aborted by Ctrl+C\n");
+
+ interrupted_query= 1;
+}
+
+
static struct my_option my_long_options[] =
{
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
@@ -591,12 +597,13 @@ static struct my_option my_long_options[] =
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory where character sets are.", (gptr*) &charsets_dir,
(gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"default-character-set", OPT_DEFAULT_CHARSET,
- "Set the default character set.", (gptr*) &default_charset,
- (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"column-type-info", OPT_COLUMN_TYPES, "Display column type information.",
+ (gptr*) &column_types_flag, (gptr*) &column_types_flag,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"compress", 'C', "Use compression in server/client protocol.",
(gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
+
#ifdef DBUG_OFF
{"debug", '#', "This is a non-debug version. Catch this and exit",
0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
@@ -604,8 +611,13 @@ static struct my_option my_long_options[] =
{"debug", '#', "Output debug log", (gptr*) &default_dbug_option,
(gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"debug-info", 'T', "Print some debug info at exit.", (gptr*) &info_flag,
+ (gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"database", 'D', "Database to use.", (gptr*) &current_db,
(gptr*) &current_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"default-character-set", OPT_DEFAULT_CHARSET,
+ "Set the default character set.", (gptr*) &default_charset,
+ (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"delimiter", OPT_DELIMITER, "Delimiter to be used.", (gptr*) &delimiter_str,
(gptr*) &delimiter_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"execute", 'e', "Execute command and quit. (Disables --force and history file)", 0,
@@ -702,8 +714,6 @@ static struct my_option my_long_options[] =
#include "sslopt-longopts.h"
{"table", 't', "Output in table format.", (gptr*) &output_tables,
(gptr*) &output_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"debug-info", 'T', "Print some debug info at exit.", (gptr*) &info_flag,
- (gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"tee", OPT_TEE,
"Append everything into outfile. See interactive help (\\h) also. Does not work in batch mode. Disable with --disable-tee. This option is disabled by default.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -729,7 +739,7 @@ static struct my_option my_long_options[] =
"Number of seconds before connection timeout.",
(gptr*) &opt_connect_timeout,
(gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0,
- 0, 1},
+ 0, 0},
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
"Max packet length to send to, or receive from server",
(gptr*) &opt_max_allowed_packet, (gptr*) &opt_max_allowed_packet, 0, GET_ULONG,
@@ -875,14 +885,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
opt_nopager= 1;
break;
case OPT_MYSQL_PROTOCOL:
- {
- if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0)
- {
- fprintf(stderr, "Unknown option to protocol: %s\n", argument);
- exit(1);
- }
+ opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
+ opt->name);
break;
- }
break;
case 'A':
opt_rehash= 0;
@@ -1021,7 +1026,7 @@ static int get_options(int argc, char **argv)
static int read_and_execute(bool interactive)
{
-#if defined(OS2) || defined(__NETWARE__)
+#if defined(__NETWARE__)
char linebuffer[254];
String buffer;
#endif
@@ -1058,9 +1063,7 @@ static int read_and_execute(bool interactive)
if (opt_outfile && glob_buffer.is_empty())
fflush(OUTFILE);
- interrupted_query= 0;
-
-#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
+#if defined( __WIN__) || defined(__NETWARE__)
tee_fputs(prompt, stdout);
#if defined(__NETWARE__)
line=fgets(linebuffer, sizeof(linebuffer)-1, stdin);
@@ -1071,7 +1074,7 @@ static int read_and_execute(bool interactive)
if (p != NULL)
*p = '\0';
}
-#elif defined(__WIN__)
+#else defined(__WIN__)
if (!tmpbuf.is_alloced())
tmpbuf.alloc(65535);
tmpbuf.length(0);
@@ -1087,32 +1090,12 @@ static int read_and_execute(bool interactive)
*/
} while (tmpbuf.alloced_length() <= clen);
line= buffer.c_ptr();
-#else /* OS2 */
- buffer.length(0);
- /* _cgets() expects the buffer size - 3 as the first byte */
- linebuffer[0]= (char) sizeof(linebuffer) - 3;
- do
- {
- line= _cgets(linebuffer);
- buffer.append(line, (unsigned char)linebuffer[1]);
- /*
- If _cgets() gets an input line that is linebuffer[0] bytes
- long, the next call to _cgets() will return immediately with
- linebuffer[1] == 0, and it does the same thing for input that
- is linebuffer[0]-1 bytes long. So it appears that even though
- _cgets() replaces the newline (which is two bytes on Window) with
- a nil, it still needs the space in the linebuffer for it. This is,
- naturally, undocumented.
- */
- } while ((unsigned char)linebuffer[0] <=
- (unsigned char)linebuffer[1] + 1);
- line= buffer.c_ptr();
#endif /* __NETWARE__ */
#else
if (opt_outfile)
fputs(prompt, OUTFILE);
line= readline(prompt);
-#endif /* defined( __WIN__) || defined(OS2) || defined(__NETWARE__) */
+#endif /* defined( __WIN__) || defined(__NETWARE__) */
/*
When Ctrl+d or Ctrl+z is pressed, the line may be NULL on some OS
@@ -1164,7 +1147,7 @@ static int read_and_execute(bool interactive)
}
}
-#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
+#if defined( __WIN__) || defined(__NETWARE__)
buffer.free();
#endif
#if defined( __WIN__)
@@ -2030,6 +2013,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
uint error= 0;
int err= 0;
+ interrupted_query= 0;
if (!status.batch)
{
old_buffer= *buffer; // Save for edit command
@@ -2065,9 +2049,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
}
timer=start_timer();
-
executing_query= 1;
-
error= mysql_real_query_for_lazy(buffer->ptr(),buffer->length());
#ifdef HAVE_READLINE
@@ -2081,8 +2063,8 @@ com_go(String *buffer,char *line __attribute__((unused)))
if (error)
{
- buffer->length(0); // Remove query on error
executing_query= 0;
+ buffer->length(0); // Remove query on error
return error;
}
error=0;
@@ -2095,7 +2077,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
if (!(result=mysql_use_result(&mysql)) && mysql_field_count(&mysql))
{
executing_query= 0;
- return put_error(&mysql);
+ return put_error(&mysql);
}
}
else
@@ -2104,7 +2086,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
if (error)
{
executing_query= 0;
- return error;
+ return error;
}
}
@@ -2114,7 +2096,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
time_buff[0]=0;
if (result)
{
- if (!mysql_num_rows(result) && ! quick && !info_flag)
+ if (!mysql_num_rows(result) && ! quick && !column_types_flag)
{
strmov(buff, "Empty set");
if (opt_xml)
@@ -2179,9 +2161,6 @@ com_go(String *buffer,char *line __attribute__((unused)))
fflush(stdout);
mysql_free_result(result);
} while (!(err= mysql_next_result(&mysql)));
-
- executing_query= 0;
-
if (err >= 1)
error= put_error(&mysql);
@@ -2196,6 +2175,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
(mysql.server_status & SERVER_STATUS_DB_DROPPED))
get_current_db();
+ executing_query= 0;
return error; /* New command follows */
}
@@ -2267,32 +2247,32 @@ com_ego(String *buffer,char *line)
static const char *fieldtype2str(enum enum_field_types type)
{
switch (type) {
- case FIELD_TYPE_BIT: return "BIT";
- case FIELD_TYPE_BLOB: return "BLOB";
- case FIELD_TYPE_DATE: return "DATE";
- case FIELD_TYPE_DATETIME: return "DATETIME";
- case FIELD_TYPE_NEWDECIMAL: return "NEWDECIMAL";
- case FIELD_TYPE_DECIMAL: return "DECIMAL";
- case FIELD_TYPE_DOUBLE: return "DOUBLE";
- case FIELD_TYPE_ENUM: return "ENUM";
- case FIELD_TYPE_FLOAT: return "FLOAT";
- case FIELD_TYPE_GEOMETRY: return "GEOMETRY";
- case FIELD_TYPE_INT24: return "INT24";
- case FIELD_TYPE_LONG: return "LONG";
- case FIELD_TYPE_LONGLONG: return "LONGLONG";
- case FIELD_TYPE_LONG_BLOB: return "LONG_BLOB";
- case FIELD_TYPE_MEDIUM_BLOB: return "MEDIUM_BLOB";
- case FIELD_TYPE_NEWDATE: return "NEWDATE";
- case FIELD_TYPE_NULL: return "NULL";
- case FIELD_TYPE_SET: return "SET";
- case FIELD_TYPE_SHORT: return "SHORT";
- case FIELD_TYPE_STRING: return "STRING";
- case FIELD_TYPE_TIME: return "TIME";
- case FIELD_TYPE_TIMESTAMP: return "TIMESTAMP";
- case FIELD_TYPE_TINY: return "TINY";
- case FIELD_TYPE_TINY_BLOB: return "TINY_BLOB";
- case FIELD_TYPE_VAR_STRING: return "VAR_STRING";
- case FIELD_TYPE_YEAR: return "YEAR";
+ case MYSQL_TYPE_BIT: return "BIT";
+ case MYSQL_TYPE_BLOB: return "BLOB";
+ case MYSQL_TYPE_DATE: return "DATE";
+ case MYSQL_TYPE_DATETIME: return "DATETIME";
+ case MYSQL_TYPE_NEWDECIMAL: return "NEWDECIMAL";
+ case MYSQL_TYPE_DECIMAL: return "DECIMAL";
+ case MYSQL_TYPE_DOUBLE: return "DOUBLE";
+ case MYSQL_TYPE_ENUM: return "ENUM";
+ case MYSQL_TYPE_FLOAT: return "FLOAT";
+ case MYSQL_TYPE_GEOMETRY: return "GEOMETRY";
+ case MYSQL_TYPE_INT24: return "INT24";
+ case MYSQL_TYPE_LONG: return "LONG";
+ case MYSQL_TYPE_LONGLONG: return "LONGLONG";
+ case MYSQL_TYPE_LONG_BLOB: return "LONG_BLOB";
+ case MYSQL_TYPE_MEDIUM_BLOB: return "MEDIUM_BLOB";
+ case MYSQL_TYPE_NEWDATE: return "NEWDATE";
+ case MYSQL_TYPE_NULL: return "NULL";
+ case MYSQL_TYPE_SET: return "SET";
+ case MYSQL_TYPE_SHORT: return "SHORT";
+ case MYSQL_TYPE_STRING: return "STRING";
+ case MYSQL_TYPE_TIME: return "TIME";
+ case MYSQL_TYPE_TIMESTAMP: return "TIMESTAMP";
+ case MYSQL_TYPE_TINY: return "TINY";
+ case MYSQL_TYPE_TINY_BLOB: return "TINY_BLOB";
+ case MYSQL_TYPE_VAR_STRING: return "VAR_STRING";
+ case MYSQL_TYPE_YEAR: return "YEAR";
default: return "?-unknown-?";
}
}
@@ -2366,7 +2346,7 @@ print_table_data(MYSQL_RES *result)
bool *num_flag;
num_flag=(bool*) my_alloca(sizeof(bool)*mysql_num_fields(result));
- if (info_flag)
+ if (column_types_flag)
{
print_field_types(result);
if (!mysql_num_rows(result))
@@ -2411,6 +2391,8 @@ print_table_data(MYSQL_RES *result)
while ((cur= mysql_fetch_row(result)))
{
+ if (interrupted_query)
+ break;
ulong *lengths= mysql_fetch_lengths(result);
(void) tee_fputs("| ", PAGER);
mysql_field_seek(result, 0);
@@ -2422,7 +2404,6 @@ print_table_data(MYSQL_RES *result)
uint visible_length;
uint extra_padding;
- /* If this column may have a null value, use "NULL" for empty. */
if (cur[off] == NULL)
{
buffer= "NULL";
@@ -2516,6 +2497,8 @@ print_table_data_html(MYSQL_RES *result)
}
while ((cur = mysql_fetch_row(result)))
{
+ if (interrupted_query)
+ break;
ulong *lengths=mysql_fetch_lengths(result);
(void) tee_fputs("<TR>", PAGER);
for (uint i=0; i < mysql_num_fields(result); i++)
@@ -2546,6 +2529,8 @@ print_table_data_xml(MYSQL_RES *result)
fields = mysql_fetch_fields(result);
while ((cur = mysql_fetch_row(result)))
{
+ if (interrupted_query)
+ break;
ulong *lengths=mysql_fetch_lengths(result);
(void) tee_fputs("\n <row>\n", PAGER);
for (uint i=0; i < mysql_num_fields(result); i++)
@@ -2585,6 +2570,8 @@ print_table_data_vertically(MYSQL_RES *result)
mysql_field_seek(result,0);
for (uint row_count=1; (cur= mysql_fetch_row(result)); row_count++)
{
+ if (interrupted_query)
+ break;
mysql_field_seek(result,0);
tee_fprintf(PAGER,
"*************************** %d. row ***************************\n", row_count);
@@ -3595,9 +3582,6 @@ void tee_fprintf(FILE *file, const char *fmt, ...)
NETWARE_YIELD;
va_start(args, fmt);
(void) vfprintf(file, fmt, args);
-#ifdef OS2
- fflush( file);
-#endif
va_end(args);
if (opt_outfile)
@@ -3613,9 +3597,6 @@ void tee_fputs(const char *s, FILE *file)
{
NETWARE_YIELD;
fputs(s, file);
-#ifdef OS2
- fflush( file);
-#endif
if (opt_outfile)
fputs(s, OUTFILE);
}
@@ -3626,9 +3607,6 @@ void tee_puts(const char *s, FILE *file)
NETWARE_YIELD;
fputs(s, file);
fputc('\n', file);
-#ifdef OS2
- fflush(file);
-#endif
if (opt_outfile)
{
fputs(s, OUTFILE);
@@ -3639,14 +3617,11 @@ void tee_puts(const char *s, FILE *file)
void tee_putc(int c, FILE *file)
{
putc(c, file);
-#ifdef OS2
- fflush( file);
-#endif
if (opt_outfile)
putc(c, OUTFILE);
}
-#if defined( __WIN__) || defined( OS2) || defined(__NETWARE__)
+#if defined( __WIN__) || defined(__NETWARE__)
#include <time.h>
#else
#include <sys/times.h>
@@ -3658,7 +3633,7 @@ void tee_putc(int c, FILE *file)
static ulong start_timer(void)
{
-#if defined( __WIN__) || defined( OS2) || defined(__NETWARE__)
+#if defined( __WIN__) || defined(__NETWARE__)
return clock();
#else
struct tms tms_tmp;
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index c7033f6914f..03b37f2ba3a 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -27,7 +27,7 @@
#include "../ndb/src/mgmclient/ndb_mgmclient.h"
#endif
-#define ADMIN_VERSION "8.41"
+#define ADMIN_VERSION "8.42"
#define MAX_MYSQL_VAR 256
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3
@@ -40,7 +40,7 @@ ulonglong last_values[MAX_MYSQL_VAR];
static int interval=0;
static my_bool option_force=0,interrupted=0,new_line=0,
opt_compress=0, opt_relative=0, opt_verbose=0, opt_vertical=0,
- tty_password=0;
+ tty_password= 0, info_flag= 0, opt_nobeep;
static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations,
opt_count_iterations= 0;
static ulong opt_connect_timeout, opt_shutdown_timeout;
@@ -54,6 +54,7 @@ static char *opt_ndb_connectstring=0;
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol=0;
+static myf error_flags; /* flags to pass to my_printf_error, like ME_BELL */
/*
When using extended-status relatively, ex_val_max_len is the estimated
@@ -135,6 +136,8 @@ static struct my_option my_long_options[] =
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (gptr*) &info_flag,
+ (gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"force", 'f',
"Don't ask for confirmation on drop database; with multiple commands, continue even if an error occurs.",
(gptr*) &option_force, (gptr*) &option_force, 0, GET_BOOL, NO_ARG, 0, 0,
@@ -152,6 +155,8 @@ static struct my_option my_long_options[] =
NO_ARG, 0, 0, 0, 0, 0, 0},
{"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"no-beep", 'b', "Turn off beep on error.", (gptr*) &opt_nobeep,
+ (gptr*) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"password", 'p',
"Password to use when connecting to server. If password is not given it's asked from the tty.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
@@ -282,15 +287,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
#endif
break;
case OPT_MYSQL_PROTOCOL:
- {
- if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0)
- {
- fprintf(stderr, "Unknown option to protocol: %s\n", argument);
- exit(1);
- }
+ opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
+ opt->name);
break;
}
- }
if (error)
{
usage();
@@ -350,6 +350,8 @@ int main(int argc,char *argv[])
#endif
if (default_charset)
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
+ error_flags= (myf)(opt_nobeep ? 0 : ME_BELL);
+
if (sql_connect(&mysql, option_wait))
{
unsigned int err= mysql_errno(&mysql);
@@ -411,7 +413,7 @@ int main(int argc,char *argv[])
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
#endif
free_defaults(save_argv);
- my_end(0);
+ my_end(info_flag ? MY_CHECK_ERROR : 0);
exit(error ? 1 : 0);
return 0;
}
@@ -448,7 +450,7 @@ static my_bool sql_connect(MYSQL *mysql, uint wait)
if (!host)
host= (char*) LOCAL_HOST;
my_printf_error(0,"connect to server at '%s' failed\nerror: '%s'",
- MYF(ME_BELL), host, mysql_error(mysql));
+ error_flags, host, mysql_error(mysql));
if (mysql_errno(mysql) == CR_CONNECTION_ERROR)
{
fprintf(stderr,
@@ -523,14 +525,14 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
char buff[FN_REFLEN+20];
if (argc < 2)
{
- my_printf_error(0,"Too few arguments to create",MYF(ME_BELL));
+ my_printf_error(0, "Too few arguments to create", error_flags);
return 1;
}
sprintf(buff,"create database `%.*s`",FN_REFLEN,argv[1]);
if (mysql_query(mysql,buff))
{
my_printf_error(0,"CREATE DATABASE failed; error: '%-.200s'",
- MYF(ME_BELL), mysql_error(mysql));
+ error_flags, mysql_error(mysql));
return -1;
}
argc--; argv++;
@@ -540,7 +542,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
{
if (argc < 2)
{
- my_printf_error(0,"Too few arguments to drop",MYF(ME_BELL));
+ my_printf_error(0, "Too few arguments to drop", error_flags);
return 1;
}
if (drop_db(mysql,argv[1]))
@@ -565,7 +567,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
if (mysql_shutdown(mysql, SHUTDOWN_DEFAULT))
{
- my_printf_error(0,"shutdown failed; error: '%s'",MYF(ME_BELL),
+ my_printf_error(0, "shutdown failed; error: '%s'", error_flags,
mysql_error(mysql));
return -1;
}
@@ -586,7 +588,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
case ADMIN_RELOAD:
if (mysql_query(mysql,"flush privileges"))
{
- my_printf_error(0,"reload failed; error: '%s'",MYF(ME_BELL),
+ my_printf_error(0, "reload failed; error: '%s'", error_flags,
mysql_error(mysql));
return -1;
}
@@ -597,7 +599,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
REFRESH_READ_LOCK | REFRESH_SLAVE |
REFRESH_MASTER)))
{
- my_printf_error(0,"refresh failed; error: '%s'",MYF(ME_BELL),
+ my_printf_error(0, "refresh failed; error: '%s'", error_flags,
mysql_error(mysql));
return -1;
}
@@ -605,7 +607,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
case ADMIN_FLUSH_THREADS:
if (mysql_refresh(mysql,(uint) REFRESH_THREADS))
{
- my_printf_error(0,"refresh failed; error: '%s'",MYF(ME_BELL),
+ my_printf_error(0, "refresh failed; error: '%s'", error_flags,
mysql_error(mysql));
return -1;
}
@@ -649,7 +651,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
"show processlist")) ||
!(result = mysql_store_result(mysql)))
{
- my_printf_error(0,"process list failed; error: '%s'",MYF(ME_BELL),
+ my_printf_error(0, "process list failed; error: '%s'", error_flags,
mysql_error(mysql));
return -1;
}
@@ -672,7 +674,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
char *pos;
if (argc < 2)
{
- my_printf_error(0,"Too few arguments to 'kill'",MYF(ME_BELL));
+ my_printf_error(0, "Too few arguments to 'kill'", error_flags);
return 1;
}
pos=argv[1];
@@ -680,7 +682,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
{
if (mysql_kill(mysql,(ulong) atol(pos)))
{
- my_printf_error(0,"kill failed on %ld; error: '%s'",MYF(ME_BELL),
+ my_printf_error(0, "kill failed on %ld; error: '%s'", error_flags,
atol(pos), mysql_error(mysql));
error=1;
}
@@ -696,7 +698,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
case ADMIN_DEBUG:
if (mysql_dump_debug_info(mysql))
{
- my_printf_error(0,"debug failed; error: '%s'",MYF(ME_BELL),
+ my_printf_error(0, "debug failed; error: '%s'", error_flags,
mysql_error(mysql));
return -1;
}
@@ -710,7 +712,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
if (mysql_query(mysql,"show /*!40003 GLOBAL */ variables") ||
!(res=mysql_store_result(mysql)))
{
- my_printf_error(0,"unable to show variables; error: '%s'",MYF(ME_BELL),
+ my_printf_error(0, "unable to show variables; error: '%s'", error_flags,
mysql_error(mysql));
return -1;
}
@@ -732,7 +734,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
if (mysql_query(mysql, "show /*!50002 GLOBAL */ status") ||
!(res = mysql_store_result(mysql)))
{
- my_printf_error(0, "unable to show status; error: '%s'", MYF(ME_BELL),
+ my_printf_error(0, "unable to show status; error: '%s'", error_flags,
mysql_error(mysql));
return -1;
}
@@ -782,7 +784,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
{
if (mysql_refresh(mysql,REFRESH_LOG))
{
- my_printf_error(0,"refresh failed; error: '%s'",MYF(ME_BELL),
+ my_printf_error(0, "refresh failed; error: '%s'", error_flags,
mysql_error(mysql));
return -1;
}
@@ -792,7 +794,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'",MYF(ME_BELL),
+ my_printf_error(0, "refresh failed; error: '%s'", error_flags,
mysql_error(mysql));
return -1;
}
@@ -802,7 +804,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'",MYF(ME_BELL),
+ my_printf_error(0, "refresh failed; error: '%s'", error_flags,
mysql_error(mysql));
return -1;
}
@@ -812,7 +814,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
{
if (mysql_query(mysql,"flush status"))
{
- my_printf_error(0,"refresh failed; error: '%s'",MYF(ME_BELL),
+ my_printf_error(0, "refresh failed; error: '%s'", error_flags,
mysql_error(mysql));
return -1;
}
@@ -829,7 +831,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
if (argc < 2)
{
- my_printf_error(0,"Too few arguments to change password",MYF(ME_BELL));
+ my_printf_error(0, "Too few arguments to change password", error_flags);
return 1;
}
if (argv[1][0])
@@ -852,7 +854,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
if (mysql_query(mysql, "SHOW VARIABLES LIKE 'old_passwords'"))
{
my_printf_error(0, "Could not determine old_passwords setting from server; error: '%s'",
- MYF(ME_BELL),mysql_error(mysql));
+ error_flags, mysql_error(mysql));
return -1;
}
else
@@ -863,7 +865,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
my_printf_error(0,
"Could not get old_passwords setting from "
"server; error: '%s'",
- MYF(ME_BELL),mysql_error(mysql));
+ error_flags, mysql_error(mysql));
return -1;
}
if (!mysql_num_rows(res))
@@ -888,7 +890,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
if (mysql_query(mysql,"set sql_log_off=1"))
{
my_printf_error(0, "Can't turn off logging; error: '%s'",
- MYF(ME_BELL),mysql_error(mysql));
+ error_flags, mysql_error(mysql));
return -1;
}
if (mysql_query(mysql,buff))
@@ -896,7 +898,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
if (mysql_errno(mysql)!=1290)
{
my_printf_error(0,"unable to change password; error: '%s'",
- MYF(ME_BELL),mysql_error(mysql));
+ error_flags, mysql_error(mysql));
return -1;
}
else
@@ -910,7 +912,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
" with grant tables disabled (was started with"
" --skip-grant-tables).\n"
"Use: \"mysqladmin flush-privileges password '*'\""
- " instead", MYF(ME_BELL));
+ " instead", error_flags);
return -1;
}
}
@@ -921,7 +923,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
case ADMIN_START_SLAVE:
if (mysql_query(mysql, "START SLAVE"))
{
- my_printf_error(0, "Error starting slave: %s", MYF(ME_BELL),
+ my_printf_error(0, "Error starting slave: %s", error_flags,
mysql_error(mysql));
return -1;
}
@@ -931,7 +933,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
case ADMIN_STOP_SLAVE:
if (mysql_query(mysql, "STOP SLAVE"))
{
- my_printf_error(0, "Error stopping slave: %s", MYF(ME_BELL),
+ my_printf_error(0, "Error stopping slave: %s", error_flags,
mysql_error(mysql));
return -1;
}
@@ -957,7 +959,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
else
{
my_printf_error(0,"mysqld doesn't answer to ping, error: '%s'",
- MYF(ME_BELL),mysql_error(mysql));
+ error_flags, mysql_error(mysql));
return -1;
}
}
@@ -968,7 +970,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
{
if (argc < 2)
{
- my_printf_error(0,"Too few arguments to ndb-mgm",MYF(ME_BELL));
+ my_printf_error(0, "Too few arguments to ndb-mgm", error_flags);
return 1;
}
{
@@ -982,7 +984,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
break;
#endif
default:
- my_printf_error(0,"Unknown command: '%-.60s'",MYF(ME_BELL),argv[0]);
+ my_printf_error(0, "Unknown command: '%-.60s'", error_flags, argv[0]);
return 1;
}
}
@@ -1060,7 +1062,7 @@ static int drop_db(MYSQL *mysql, const char *db)
sprintf(name_buff,"drop database `%.*s`",FN_REFLEN,db);
if (mysql_query(mysql,name_buff))
{
- my_printf_error(0,"DROP DATABASE %s failed;\nerror: '%s'",MYF(ME_BELL),
+ my_printf_error(0, "DROP DATABASE %s failed;\nerror: '%s'", error_flags,
db,mysql_error(mysql));
return 1;
}
@@ -1285,7 +1287,7 @@ static my_bool get_pidfile(MYSQL *mysql, char *pidfile)
if (mysql_query(mysql, "SHOW VARIABLES LIKE 'pid_file'"))
{
- my_printf_error(0,"query failed; error: '%s'",MYF(ME_BELL),
+ my_printf_error(0, "query failed; error: '%s'", error_flags,
mysql_error(mysql));
}
result = mysql_store_result(mysql);
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index a371981e24d..033c55707fc 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -63,8 +63,10 @@ void sql_print_error(const char *format, ...);
static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0;
static bool opt_hexdump= 0;
+static bool opt_base64_output= 0;
static const char* database= 0;
-static my_bool force_opt= 0, short_form= 0, remote_opt= 0;
+static my_bool force_opt= 0, short_form= 0, remote_opt= 0, info_flag;
+static my_bool force_if_open_opt= 1;
static ulonglong offset = 0;
static const char* host = 0;
static int port= 0;
@@ -84,6 +86,7 @@ static short binlog_flags = 0;
static MYSQL* mysql = NULL;
static const char* dirname_for_local_load= 0;
static bool stop_passed= 0;
+static my_bool file_not_closed_error= 0;
/*
check_header() will set the pointer below.
@@ -473,6 +476,25 @@ static bool check_database(const char *log_dbname)
}
+
+static int
+write_event_header_and_base64(Log_event *ev, FILE *result_file,
+ PRINT_EVENT_INFO *print_event_info)
+{
+ IO_CACHE *head= &print_event_info->head_cache;
+ IO_CACHE *body= &print_event_info->body_cache;
+ DBUG_ENTER("write_event_header_and_base64");
+
+ /* Write header and base64 output to cache */
+ ev->print_header(head, print_event_info, FALSE);
+ ev->print_base64(body, print_event_info, FALSE);
+
+ /* Read data from cache and write to result file */
+ DBUG_RETURN(copy_event_cache_to_file_and_reinit(head, result_file) ||
+ copy_event_cache_to_file_and_reinit(body, result_file));
+}
+
+
/*
Process an event
@@ -516,6 +538,9 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
start_datetime= 0;
offset= 0; // print everything and protect against cycling rec_count
}
+ if (server_id && (server_id != ev->server_id)) {
+ DBUG_RETURN(0);
+ }
if (((my_time_t)(ev->when) >= stop_datetime)
|| (pos >= stop_position_mot))
{
@@ -530,12 +555,20 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
else
print_event_info->hexdump_from= pos;
+ print_event_info->base64_output= opt_base64_output;
+
+ DBUG_PRINT("debug", ("event_type: %s", ev->get_type_str()));
+
switch (ev_type) {
case QUERY_EVENT:
if (check_database(((Query_log_event*)ev)->db))
goto end;
- ev->print(result_file, print_event_info);
+ if (opt_base64_output)
+ write_event_header_and_base64(ev, result_file, print_event_info);
+ else
+ ev->print(result_file, print_event_info);
break;
+
case CREATE_FILE_EVENT:
{
Create_file_log_event* ce= (Create_file_log_event*)ev;
@@ -554,7 +587,12 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
filename and use LOCAL), prepared in the 'case EXEC_LOAD_EVENT'
below.
*/
- ce->print(result_file, print_event_info, TRUE);
+ if (opt_base64_output)
+ {
+ write_event_header_and_base64(ce, result_file, print_event_info);
+ }
+ else
+ ce->print(result_file, print_event_info, TRUE);
// If this binlog is not 3.23 ; why this test??
if (glob_description_event->binlog_version >= 3)
@@ -594,7 +632,8 @@ Create_file event for file_id: %u\n",exv->file_id);
case FORMAT_DESCRIPTION_EVENT:
delete glob_description_event;
glob_description_event= (Format_description_log_event*) ev;
- print_event_info->common_header_len= glob_description_event->common_header_len;
+ print_event_info->common_header_len=
+ glob_description_event->common_header_len;
ev->print(result_file, print_event_info);
/*
We don't want this event to be deleted now, so let's hide it (I
@@ -603,6 +642,12 @@ Create_file event for file_id: %u\n",exv->file_id);
later.
*/
ev= 0;
+ if (!force_if_open_opt &&
+ (glob_description_event->flags & LOG_EVENT_BINLOG_IN_USE_F))
+ {
+ file_not_closed_error= 1;
+ DBUG_RETURN(1);
+ }
break;
case BEGIN_LOAD_QUERY_EVENT:
ev->print(result_file, print_event_info);
@@ -645,11 +690,18 @@ end:
static struct my_option my_long_options[] =
{
-
+ {"help", '?', "Display this help and exit.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef __NETWARE__
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"base64-output", OPT_BASE64_OUTPUT,
+ "Print all binlog entries using base64 encoding. "
+ "This is for debugging only. Logs produced using this option "
+ "should not be applied on production systems.",
+ (gptr*) &opt_base64_output, (gptr*) &opt_base64_output, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
/*
mysqlbinlog needs charsets knowledge, to be able to convert a charset
number found in binlog to a charset name (to be able to print things
@@ -659,13 +711,15 @@ static struct my_option my_long_options[] =
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory where character sets are.", (gptr*) &charsets_dir,
(gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"database", 'd', "List entries for just this database (local log only).",
+ (gptr*) &database, (gptr*) &database, 0, GET_STR_ALLOC, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF
{"debug", '#', "Output debug log.", (gptr*) &default_dbug_option,
(gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"database", 'd', "List entries for just this database (local log only).",
- (gptr*) &database, (gptr*) &database, 0, GET_STR_ALLOC, REQUIRED_ARG,
- 0, 0, 0, 0, 0, 0},
+ {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (gptr*) &info_flag,
+ (gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"disable-log-bin", 'D', "Disable binary log. This is useful, if you "
"enabled --to-last-log and are sending the output to the same MySQL server. "
"This way you could avoid an endless loop. You would also like to use it "
@@ -673,16 +727,20 @@ static struct my_option my_long_options[] =
"already have. NOTE: you will need a SUPER privilege to use this option.",
(gptr*) &disable_log_bin, (gptr*) &disable_log_bin, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"force-if-open", 'F', "Force if binlog was not closed properly.",
+ (gptr*) &force_if_open_opt, (gptr*) &force_if_open_opt, 0, GET_BOOL, NO_ARG,
+ 1, 0, 0, 0, 0, 0},
{"force-read", 'f', "Force reading unknown binlog events.",
(gptr*) &force_opt, (gptr*) &force_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
- {"help", '?', "Display this help and exit.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"hexdump", 'H', "Augment output with hexadecimal and ASCII event dump.",
(gptr*) &opt_hexdump, (gptr*) &opt_hexdump, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
{"host", 'h', "Get the binlog from server.", (gptr*) &host, (gptr*) &host,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"local-load", 'l', "Prepare local temporary files for LOAD DATA INFILE in the specified directory.",
+ (gptr*) &dirname_for_local_load, (gptr*) &dirname_for_local_load, 0,
+ GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"offset", 'o', "Skip the first N entries.", (gptr*) &offset, (gptr*) &offset,
0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"password", 'p', "Password to connect to remote server.",
@@ -698,15 +756,15 @@ static struct my_option my_long_options[] =
{"protocol", OPT_MYSQL_PROTOCOL,
"The protocol of connection (tcp,socket,pipe,memory).",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"result-file", 'r', "Direct output to a given file.", 0, 0, 0, GET_STR,
- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"read-from-remote-server", 'R', "Read binary logs from a MySQL server",
(gptr*) &remote_opt, (gptr*) &remote_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
- {"open_files_limit", OPT_OPEN_FILES_LIMIT,
- "Used to reserve file descriptors for usage by this program",
- (gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG,
- REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0},
+ {"result-file", 'r', "Direct output to a given file.", 0, 0, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"server-id", OPT_SERVER_ID,
+ "Extract only binlog entries created by the server having the given id.",
+ (gptr*) &server_id, (gptr*) &server_id, 0, GET_ULONG,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"set-charset", OPT_SET_CHARSET,
"Add 'SET NAMES character_set' to the output.", (gptr*) &charset,
(gptr*) &charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -724,6 +782,13 @@ static struct my_option my_long_options[] =
"(you should probably use quotes for your shell to set it properly).",
(gptr*) &start_datetime_str, (gptr*) &start_datetime_str,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"start-position", OPT_START_POSITION,
+ "Start reading the binlog at position N. Applies to the first binlog "
+ "passed on the command line.",
+ (gptr*) &start_position, (gptr*) &start_position, 0, GET_ULL,
+ REQUIRED_ARG, BIN_LOG_HEADER_SIZE, BIN_LOG_HEADER_SIZE,
+ /* COM_BINLOG_DUMP accepts only 4 bytes for the position */
+ (ulonglong)(~(uint32)0), 0, 0, 0},
{"stop-datetime", OPT_STOP_DATETIME,
"Stop reading the binlog at first event having a datetime equal or "
"posterior to the argument; the argument must be a date and time "
@@ -732,13 +797,6 @@ static struct my_option my_long_options[] =
"(you should probably use quotes for your shell to set it properly).",
(gptr*) &stop_datetime_str, (gptr*) &stop_datetime_str,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"start-position", OPT_START_POSITION,
- "Start reading the binlog at position N. Applies to the first binlog "
- "passed on the command line.",
- (gptr*) &start_position, (gptr*) &start_position, 0, GET_ULL,
- REQUIRED_ARG, BIN_LOG_HEADER_SIZE, BIN_LOG_HEADER_SIZE,
- /* COM_BINLOG_DUMP accepts only 4 bytes for the position */
- (ulonglong)(~(uint32)0), 0, 0, 0},
{"stop-position", OPT_STOP_POSITION,
"Stop reading the binlog at position N. Applies to the last binlog "
"passed on the command line.",
@@ -754,11 +812,12 @@ that may lead to an endless loop.",
{"user", 'u', "Connect to the remote server as username.",
(gptr*) &user, (gptr*) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0,
0, 0},
- {"local-load", 'l', "Prepare local temporary files for LOAD DATA INFILE in the specified directory.",
- (gptr*) &dirname_for_local_load, (gptr*) &dirname_for_local_load, 0,
- GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
0, 0, 0, 0, 0},
+ {"open_files_limit", OPT_OPEN_FILES_LIMIT,
+ "Used to reserve file descriptors for usage by this program",
+ (gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG,
+ REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -792,7 +851,7 @@ static void die(const char* fmt, ...)
va_end(args);
cleanup();
/* We cannot free DBUG, it is used in global destructors after exit(). */
- my_end(MY_DONT_FREE_DBUG);
+ my_end((info_flag ? MY_CHECK_ERROR : 0) | MY_DONT_FREE_DBUG);
exit(1);
}
@@ -885,14 +944,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
remote_opt= 1;
break;
case OPT_MYSQL_PROTOCOL:
- {
- if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0)
- {
- fprintf(stderr, "Unknown option to protocol: %s\n", argument);
- exit(1);
- }
+ opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
+ opt->name);
break;
- }
case OPT_START_DATETIME:
start_datetime= convert_str_to_timestamp(start_datetime_str);
break;
@@ -950,6 +1004,9 @@ static int dump_log_entries(const char* logname)
{
int rc;
PRINT_EVENT_INFO print_event_info;
+
+ if (!print_event_info.init_ok())
+ return 1;
/*
Set safe delimiter, to dump things
like CREATE PROCEDURE safely
@@ -1340,15 +1397,12 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
else // reading from stdin;
{
/*
- Bug fix: #23735
- Author: Chuck Bell
- Description:
- Windows opens stdin in text mode by default. Certain characters
- such as CTRL-Z are interpeted as events and the read() method
- will stop. CTRL-Z is the EOF marker in Windows. to get past this
- you have to open stdin in binary mode. Setmode() is used to set
- stdin in binary mode. Errors on setting this mode result in
- halting the function and printing an error message to stderr.
+ Windows opens stdin in text mode by default. Certain characters
+ such as CTRL-Z are interpeted as events and the read() method
+ will stop. CTRL-Z is the EOF marker in Windows. to get past this
+ you have to open stdin in binary mode. Setmode() is used to set
+ stdin in binary mode. Errors on setting this mode result in
+ halting the function and printing an error message to stderr.
*/
#if defined (__WIN__) || (_WIN64)
if (_setmode(fileno(stdin), O_BINARY) == -1)
@@ -1356,8 +1410,7 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
fprintf(stderr, "Could not set binary mode on stdin.\n");
return 1;
}
-#endif
-
+#endif
if (init_io_cache(file, fileno(stdin), 0, READ_CACHE, (my_off_t) 0,
0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE)))
return 1;
@@ -1431,7 +1484,7 @@ end:
int main(int argc, char** argv)
{
- static char **defaults_argv;
+ char **defaults_argv;
int exit_value= 0;
ulonglong save_stop_position;
MY_INIT(argv[0]);
@@ -1529,7 +1582,17 @@ int main(int argc, char** argv)
my_free_open_file_info();
load_processor.destroy();
/* We cannot free DBUG, it is used in global destructors after exit(). */
- my_end(MY_DONT_FREE_DBUG);
+ my_end((info_flag ? MY_CHECK_ERROR : 0) | MY_DONT_FREE_DBUG);
+
+ if (file_not_closed_error)
+ {
+ fprintf(stderr,
+"\nError: attempting to dump binlog '%s' which was not closed properly.\n"
+"Most probably mysqld is still writting it, or crashed.\n"
+"Your current options specify --disable-force-if-open\n"
+"which means to abort on this problem.\n"
+"You can rerun using --force-if-open to ignore this problem.\n\n", argv[-1]);
+ }
exit(exit_value);
DBUG_RETURN(exit_value); // Keep compilers happy
}
@@ -1539,14 +1602,17 @@ int main(int argc, char** argv)
the server
*/
+#if defined(__WIN__) && !defined(USING_CMAKE)
#include "my_decimal.h"
#include "decimal.c"
-
-#if defined(__WIN__) && !defined(CMAKE_BUILD)
#include "my_decimal.cpp"
#include "log_event.cpp"
+#include "log_event_old.cpp"
#else
+#include "my_decimal.h"
+#include "decimal.c"
#include "my_decimal.cc"
#include "log_event.cc"
+#include "log_event_old.cc"
#endif
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index b69e9201a28..43a938badbe 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -15,7 +15,7 @@
/* By Jani Tolonen, 2001-04-20, MySQL Development Team */
-#define CHECK_VERSION "2.4.4"
+#define CHECK_VERSION "2.4.5"
#include "client_priv.h"
#include <m_ctype.h>
@@ -33,7 +33,9 @@ static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0,
opt_compress = 0, opt_databases = 0, opt_fast = 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, opt_upgrade= 0;
+ tty_password= 0, opt_frm= 0, info_flag= 0,
+ opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0,
+ opt_write_binlog= 1;
static uint verbose = 0, opt_mysql_port=0;
static my_string opt_mysql_unix_port = 0;
static char *opt_password = 0, *current_user = 0,
@@ -47,7 +49,7 @@ static char *shared_memory_base_name=0;
static uint opt_protocol=0;
static CHARSET_INFO *charset_info= &my_charset_latin1;
-enum operations {DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE};
+enum operations { DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE };
static struct my_option my_long_options[] =
{
@@ -94,12 +96,20 @@ static struct my_option my_long_options[] =
{"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (gptr*) &info_flag,
+ (gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"default-character-set", OPT_DEFAULT_CHARSET,
"Set the default character set.", (gptr*) &default_charset,
(gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"fast",'F', "Check only tables that haven't been closed properly.",
(gptr*) &opt_fast, (gptr*) &opt_fast, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
0},
+ {"fix-db-names", OPT_FIX_DB_NAMES, "Fix database names.",
+ (gptr*) &opt_fix_db_names, (gptr*) &opt_fix_db_names,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"fix-table-names", OPT_FIX_TABLE_NAMES, "Fix table names.",
+ (gptr*) &opt_fix_table_names, (gptr*) &opt_fix_table_names,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"force", 'f', "Continue even if we get an sql-error.",
(gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
0, 0, 0, 0},
@@ -114,6 +124,10 @@ static struct my_option my_long_options[] =
{"medium-check", 'm',
"Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"write-binlog", OPT_WRITE_BINLOG,
+ "Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Enabled by default; use --skip-write-binlog when commands should not be sent to replication slaves.",
+ (gptr*) &opt_write_binlog, (gptr*) &opt_write_binlog, 0, GET_BOOL, NO_ARG,
+ 1, 0, 0, 0, 0, 0},
{"optimize", 'o', "Optimize table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
0, 0},
{"password", 'p',
@@ -173,6 +187,7 @@ static int process_all_databases();
static int process_databases(char **db_names);
static int process_selected_tables(char *db, char **table_names, int tables);
static int process_all_tables_in_db(char *database);
+static int process_one_db(char *database);
static int use_db(char *database);
static int handle_request_for_tables(char *tables, uint length);
static int dbConnect(char *host, char *user,char *passwd);
@@ -253,6 +268,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case 'o':
what_to_do = DO_OPTIMIZE;
break;
+ case OPT_FIX_DB_NAMES:
+ what_to_do= DO_UPGRADE;
+ default_charset= (char*) "utf8";
+ opt_databases= 1;
+ break;
+ case OPT_FIX_TABLE_NAMES:
+ what_to_do= DO_UPGRADE;
+ default_charset= (char*) "utf8";
+ break;
case 'p':
if (argument)
{
@@ -291,15 +315,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'V': print_version(); exit(0);
case OPT_MYSQL_PROTOCOL:
- {
- if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0)
- {
- fprintf(stderr, "Unknown option to protocol: %s\n", argument);
- exit(1);
- }
+ opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
+ opt->name);
break;
}
- }
return 0;
}
@@ -375,7 +394,7 @@ static int process_all_databases()
}
while ((row = mysql_fetch_row(tableres)))
{
- if (process_all_tables_in_db(row[0]))
+ if (process_one_db(row[0]))
result = 1;
}
return result;
@@ -388,7 +407,7 @@ static int process_databases(char **db_names)
int result = 0;
for ( ; *db_names ; db_names++)
{
- if (process_all_tables_in_db(*db_names))
+ if (process_one_db(*db_names))
result = 1;
}
return result;
@@ -509,6 +528,43 @@ static int process_all_tables_in_db(char *database)
} /* process_all_tables_in_db */
+
+static int fix_object_name(const char *obj, const char *name)
+{
+ char qbuf[100 + NAME_LEN*4];
+ int rc= 0;
+ if (strncmp(name, "#mysql50#", 9))
+ return 1;
+ sprintf(qbuf, "RENAME %s `%s` TO `%s`", obj, name, name + 9);
+ if (mysql_query(sock, qbuf))
+ {
+ fprintf(stderr, "Failed to %s\n", qbuf);
+ fprintf(stderr, "Error: %s\n", mysql_error(sock));
+ rc= 1;
+ }
+ if (verbose)
+ printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
+ return rc;
+}
+
+
+static int process_one_db(char *database)
+{
+ if (what_to_do == DO_UPGRADE)
+ {
+ int rc= 0;
+ if (opt_fix_db_names && !strncmp(database,"#mysql50#", 9))
+ {
+ rc= fix_object_name("DATABASE", database);
+ database+= 9;
+ }
+ if (rc || !opt_fix_table_names)
+ return rc;
+ }
+ return process_all_tables_in_db(database);
+}
+
+
static int use_db(char *database)
{
if (mysql_get_server_version(sock) >= 50003 &&
@@ -542,17 +598,19 @@ static int handle_request_for_tables(char *tables, uint length)
if (opt_upgrade) end = strmov(end, " FOR UPGRADE");
break;
case DO_REPAIR:
- op = "REPAIR";
+ op= (opt_write_binlog) ? "REPAIR" : "REPAIR NO_WRITE_TO_BINLOG";
if (opt_quick) end = strmov(end, " QUICK");
if (opt_extended) end = strmov(end, " EXTENDED");
if (opt_frm) end = strmov(end, " USE_FRM");
break;
case DO_ANALYZE:
- op = "ANALYZE";
+ op= (opt_write_binlog) ? "ANALYZE" : "ANALYZE NO_WRITE_TO_BINLOG";
break;
case DO_OPTIMIZE:
- op = "OPTIMIZE";
+ op= (opt_write_binlog) ? "OPTIMIZE" : "OPTIMIZE NO_WRITE_TO_BINLOG";
break;
+ case DO_UPGRADE:
+ return fix_object_name("TABLE", tables);
}
if (!(query =(char *) my_malloc((sizeof(char)*(length+110)), MYF(MY_WME))))
@@ -704,7 +762,7 @@ int main(int argc, char **argv)
*/
if (get_options(&argc, &argv))
{
- my_end(0);
+ my_end(info_flag ? MY_CHECK_ERROR : 0);
exit(EX_USAGE);
}
if (dbConnect(current_host, current_user, opt_password))
@@ -746,6 +804,6 @@ int main(int argc, char **argv)
#ifdef HAVE_SMEM
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
#endif
- my_end(0);
+ my_end(info_flag ? MY_CHECK_ERROR : 0);
return(first_error!=0);
} /* main */
diff --git a/client/mysqldump.c b/client/mysqldump.c
index b334e8d9a11..fa25701eb91 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -29,14 +29,14 @@
** master/autocommit code by Brian Aker <brian@tangent.org>
** SSL by
** Andrei Errapart <andreie@no.spam.ee>
-** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
+** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
** XML by Gary Huntress <ghuntress@mediaone.net> 10/10/01, cleaned up
** and adapted to mysqldump 05/11/01 by Jani Tolonen
** Added --single-transaction option 06/06/2002 by Peter Zaitsev
** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov
*/
-#define DUMP_VERSION "10.11"
+#define DUMP_VERSION "10.12"
#include <my_global.h>
#include <my_sys.h>
@@ -50,6 +50,7 @@
#include "mysql.h"
#include "mysql_version.h"
#include "mysqld_error.h"
+#include "../sql/ha_ndbcluster_tables.h"
/* Exit codes */
@@ -95,7 +96,10 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0,
opt_single_transaction=0, opt_comments= 0, opt_compact= 0,
opt_hex_blob=0, opt_order_by_primary=0, opt_ignore=0,
opt_complete_insert= 0, opt_drop_database= 0,
- opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1;
+ opt_replace_into= 0,
+ opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1,
+ opt_events= 0,
+ opt_alltspcs=0, opt_notspcs= 0;
static ulong opt_max_allowed_packet, opt_net_buffer_length;
static MYSQL mysql_connection,*mysql=0;
static my_bool insert_pat_inited= 0, info_flag;
@@ -149,7 +153,6 @@ static CHARSET_INFO *charset_info= &my_charset_latin1;
const char *default_dbug_option="d:t:o,/tmp/mysqldump.trace";
/* have we seen any VIEWs during table scanning? */
my_bool seen_views= 0;
-
const char *compatible_mode_names[]=
{
"MYSQL323", "MYSQL40", "POSTGRESQL", "ORACLE", "MSSQL", "DB2",
@@ -180,6 +183,14 @@ static struct my_option my_long_options[] =
"Dump all the databases. This will be same as --databases with all databases selected.",
(gptr*) &opt_alldbs, (gptr*) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
+ {"all-tablespaces", 'Y',
+ "Dump all the tablespaces.",
+ (gptr*) &opt_alltspcs, (gptr*) &opt_alltspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
+ {"no-tablespaces", 'y',
+ "Do not dump any tablespace information.",
+ (gptr*) &opt_notspcs, (gptr*) &opt_notspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
{"add-drop-database", OPT_DROP_DATABASE, "Add a 'DROP DATABASE' before each create.",
(gptr*) &opt_drop_database, (gptr*) &opt_drop_database, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
0},
@@ -246,6 +257,9 @@ static struct my_option my_long_options[] =
{"disable-keys", 'K',
"'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (gptr*) &opt_disable_keys,
(gptr*) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"events", 'E', "Dump events.",
+ (gptr*) &opt_events, (gptr*) &opt_events, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
{"extended-insert", 'e',
"Allows utilization of the new, much faster INSERT syntax.",
(gptr*) &extended_insert, (gptr*) &extended_insert, 0, GET_BOOL, NO_ARG,
@@ -371,6 +385,9 @@ static struct my_option my_long_options[] =
{"quote-names",'Q', "Quote table and column names with backticks (`).",
(gptr*) &opt_quoted, (gptr*) &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
0, 0},
+ {"replace", OPT_MYSQL_REPLACE_INTO, "Use REPLACE INTO instead of INSERT INTO.",
+ (gptr*) &opt_replace_into, (gptr*) &opt_replace_into, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0},
{"result-file", 'r',
"Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\r\\n' (carriage return + line feed).",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -457,6 +474,10 @@ char check_if_ignore_table(const char *table_name, char *table_type);
static char *primary_key_fields(const char *table_name);
static my_bool get_view_structure(char *table, char* db);
static my_bool dump_all_views_in_db(char *database);
+static int dump_all_tablespaces();
+static int dump_tablespaces_for_tables(char *db, char **table_names, int tables);
+static int dump_tablespaces_for_databases(char** databases);
+static int dump_tablespaces(char* ts_where);
#include <help_start.h>
@@ -543,8 +564,10 @@ static void write_header(FILE *sql_file, char *db_name)
if (opt_xml)
{
fputs("<?xml version=\"1.0\"?>\n", sql_file);
- /* Schema reference. Allows use of xsi:nil for NULL values and
- xsi:type to define an element's data type. */
+ /*
+ Schema reference. Allows use of xsi:nil for NULL values and
+ xsi:type to define an element's data type.
+ */
fputs("<mysqldump ", sql_file);
fputs("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"",
sql_file);
@@ -784,14 +807,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
}
case (int) OPT_MYSQL_PROTOCOL:
- {
- if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0)
- {
- fprintf(stderr, "Unknown option to protocol: %s\n", argument);
- exit(1);
- }
- break;
- }
+ opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
+ opt->name);
+ break;
}
return 0;
}
@@ -812,11 +830,15 @@ static int get_options(int *argc, char ***argv)
(hash_get_key) get_table_key,
(hash_free_key) free_table_ent, 0))
return(EX_EOM);
- /* Don't copy cluster internal log tables */
+ /* Don't copy internal log tables */
if (my_hash_insert(&ignore_table,
(byte*) my_strdup("mysql.apply_status", MYF(MY_WME))) ||
my_hash_insert(&ignore_table,
- (byte*) my_strdup("mysql.schema", MYF(MY_WME))))
+ (byte*) my_strdup("mysql.schema", MYF(MY_WME))) ||
+ my_hash_insert(&ignore_table,
+ (byte*) my_strdup("mysql.general_log", MYF(MY_WME))) ||
+ my_hash_insert(&ignore_table,
+ (byte*) my_strdup("mysql.slow_log", MYF(MY_WME))))
return(EX_EOM);
if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
@@ -1395,6 +1417,136 @@ static void print_xml_row(FILE *xml_file, const char *row_name,
check_io(xml_file);
}
+
+/*
+ create_delimiter
+ Generate a new (null-terminated) string that does not exist in query
+ and is therefore suitable for use as a query delimiter. Store this
+ delimiter in delimiter_buff .
+
+ This is quite simple in that it doesn't even try to parse statements as an
+ interpreter would. It merely returns a string that is not in the query, which
+ is much more than adequate for constructing a delimiter.
+
+ RETURN
+ ptr to the delimiter on Success
+ NULL on Failure
+*/
+static char *create_delimiter(char *query, char *delimiter_buff,
+ int delimiter_max_size)
+{
+ int proposed_length;
+ char *presence;
+
+ delimiter_buff[0]= ';'; /* start with one semicolon, and */
+
+ for (proposed_length= 2; proposed_length < delimiter_max_size;
+ delimiter_max_size++) {
+
+ delimiter_buff[proposed_length-1]= ';'; /* add semicolons, until */
+ delimiter_buff[proposed_length]= '\0';
+
+ presence = strstr(query, delimiter_buff);
+ if (presence == NULL) { /* the proposed delimiter is not in the query. */
+ return delimiter_buff;
+ }
+
+ }
+ return NULL; /* but if we run out of space, return nothing at all. */
+}
+
+
+/*
+ dump_events_for_db
+ -- retrieves list of events for a given db, and prints out
+ the CREATE EVENT statement into the output (the dump).
+
+ RETURN
+ 0 Success
+ 1 Error
+*/
+static uint dump_events_for_db(char *db)
+{
+ char query_buff[QUERY_LENGTH];
+ char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
+ char *event_name;
+ char delimiter[QUERY_LENGTH], *delimit_test;
+ FILE *sql_file= md_result_file;
+ MYSQL_RES *event_res, *event_list_res;
+ MYSQL_ROW row, event_list_row;
+ DBUG_ENTER("dump_events_for_db");
+ DBUG_PRINT("enter", ("db: '%s'", db));
+
+ mysql_real_escape_string(mysql, db_name_buff, db, strlen(db));
+
+ /* nice comments */
+ if (opt_comments)
+ fprintf(sql_file, "\n--\n-- Dumping events for database '%s'\n--\n", db);
+
+ /*
+ not using "mysql_query_with_error_report" because we may have not
+ enough privileges to lock mysql.events.
+ */
+ if (lock_tables)
+ mysql_query(mysql, "LOCK TABLES mysql.event READ");
+
+ if (mysql_query_with_error_report(mysql, &event_list_res, "show events"))
+ DBUG_RETURN(0);
+
+ strcpy(delimiter, ";");
+ if (mysql_num_rows(event_list_res) > 0)
+ {
+ fprintf(sql_file, "/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;\n");
+
+ while ((event_list_row= mysql_fetch_row(event_list_res)) != NULL)
+ {
+ event_name= quote_name(event_list_row[1], name_buff, 0);
+ DBUG_PRINT("info", ("retrieving CREATE EVENT for %s", name_buff));
+ my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE EVENT %s",
+ event_name);
+
+ if (mysql_query_with_error_report(mysql, &event_res, query_buff))
+ DBUG_RETURN(1);
+
+ while ((row= mysql_fetch_row(event_res)) != NULL)
+ {
+ /*
+ if the user has EXECUTE privilege he can see event names, but not the
+ event body!
+ */
+ if (strlen(row[3]) != 0)
+ {
+ if (opt_drop)
+ fprintf(sql_file, "/*!50106 DROP EVENT IF EXISTS %s */%s\n",
+ event_name, delimiter);
+
+ delimit_test= create_delimiter(row[3], delimiter, sizeof(delimiter));
+ if (delimit_test == NULL) {
+ fprintf(stderr, "%s: Warning: Can't dump event '%s'\n",
+ event_name, my_progname);
+ DBUG_RETURN(1);
+ }
+
+ fprintf(sql_file, "DELIMITER %s\n", delimiter);
+ fprintf(sql_file, "/*!50106 SET TIME_ZONE= '%s' */ %s\n",
+ row[2], delimiter);
+ fprintf(sql_file, "/*!50106 %s */ %s\n", row[3], delimiter);
+ }
+ } /* end of event printing */
+ mysql_free_result(event_res);
+
+ } /* end of list of events */
+ fprintf(sql_file, "DELIMITER ;\n");
+ fprintf(sql_file, "/*!50106 SET TIME_ZONE= @save_time_zone */ ;\n");
+ }
+ mysql_free_result(event_list_res);
+
+ if (lock_tables)
+ VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+ DBUG_RETURN(0);
+}
+
+
/*
Print hex value for blob data.
@@ -1432,7 +1584,7 @@ static void print_blob_as_hex(FILE *output_file, const char *str, ulong len)
static uint dump_routines_for_db(char *db)
{
- char query_buff[512];
+ char query_buff[QUERY_LENGTH];
const char *routine_type[]= {"FUNCTION", "PROCEDURE"};
char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
char *routine_name;
@@ -1476,9 +1628,9 @@ static uint dump_routines_for_db(char *db)
while ((routine_list_row= mysql_fetch_row(routine_list_res)))
{
+ routine_name= quote_name(routine_list_row[1], name_buff, 0);
DBUG_PRINT("info", ("retrieving CREATE %s for %s", routine_type[i],
name_buff));
- routine_name= quote_name(routine_list_row[1], name_buff, 0);
my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE %s %s",
routine_type[i], routine_name);
@@ -1598,8 +1750,8 @@ static uint get_table_structure(char *table, char *db, char *table_type,
my_ulonglong num_fields;
char *result_table, *opt_quoted_table;
const char *insert_option;
- char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
- char table_buff2[NAME_LEN*2+3], query_buff[512];
+ char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
+ char table_buff2[NAME_LEN*2+3], query_buff[QUERY_LENGTH];
FILE *sql_file= md_result_file;
int len;
MYSQL_RES *result;
@@ -1803,7 +1955,10 @@ static uint get_table_structure(char *table, char *db, char *table_type,
*/
if (write_data)
{
- dynstr_append_checked(&insert_pat, "INSERT ");
+ if (opt_replace_into)
+ dynstr_append_checked(&insert_pat, "REPLACE ");
+ else
+ dynstr_append_checked(&insert_pat, "INSERT ");
dynstr_append_checked(&insert_pat, insert_option);
dynstr_append_checked(&insert_pat, "INTO ");
dynstr_append_checked(&insert_pat, opt_quoted_table);
@@ -1869,7 +2024,10 @@ static uint get_table_structure(char *table, char *db, char *table_type,
if (write_data)
{
- dynstr_append_checked(&insert_pat, "INSERT ");
+ if (opt_replace_into)
+ dynstr_append_checked(&insert_pat, "REPLACE ");
+ else
+ dynstr_append_checked(&insert_pat, "INSERT ");
dynstr_append_checked(&insert_pat, insert_option);
dynstr_append_checked(&insert_pat, "INTO ");
dynstr_append_checked(&insert_pat, result_table);
@@ -2086,7 +2244,7 @@ static void dump_triggers_for_table(char *table,
{
char *result_table;
char name_buff[NAME_LEN*4+3], table_buff[NAME_LEN*2+3];
- char query_buff[512];
+ char query_buff[QUERY_LENGTH];
uint old_opt_compatible_mode=opt_compatible_mode;
FILE *sql_file= md_result_file;
MYSQL_RES *result;
@@ -2565,7 +2723,7 @@ static void dump_table(char *table, char *db)
dynstr_append_checked(&extended_row, "NULL");
else
{
- if (field->type == FIELD_TYPE_DECIMAL)
+ if (field->type == MYSQL_TYPE_DECIMAL)
{
/* add " signs around */
dynstr_append_checked(&extended_row, "'");
@@ -2634,7 +2792,7 @@ static void dump_table(char *table, char *db)
else if (my_isalpha(charset_info, *ptr) ||
(*ptr == '-' && my_isalpha(charset_info, ptr[1])))
fputs("NULL", md_result_file);
- else if (field->type == FIELD_TYPE_DECIMAL)
+ else if (field->type == MYSQL_TYPE_DECIMAL)
{
/* add " signs around */
fputc('\'', md_result_file);
@@ -2768,6 +2926,256 @@ static char *getTableName(int reset)
} /* getTableName */
+/*
+ dump all logfile groups and tablespaces
+*/
+
+static int dump_all_tablespaces()
+{
+ return dump_tablespaces(NULL);
+}
+
+static int dump_tablespaces_for_tables(char *db, char **table_names, int tables)
+{
+ DYNAMIC_STRING where;
+ int r;
+ int i;
+ char name_buff[NAME_LEN*2+3];
+
+ mysql_real_escape_string(mysql, name_buff, db, strlen(db));
+
+ init_dynamic_string_checked(&where, " AND TABLESPACE_NAME IN ("
+ "SELECT DISTINCT TABLESPACE_NAME FROM"
+ " INFORMATION_SCHEMA.PARTITIONS"
+ " WHERE"
+ " TABLE_SCHEMA='", 256, 1024);
+ dynstr_append_checked(&where, name_buff);
+ dynstr_append_checked(&where, "' AND TABLE_NAME IN (");
+
+ for (i=0 ; i<tables ; i++)
+ {
+ mysql_real_escape_string(mysql, name_buff,
+ table_names[i], strlen(table_names[i]));
+
+ dynstr_append_checked(&where, "'");
+ dynstr_append_checked(&where, name_buff);
+ dynstr_append_checked(&where, "',");
+ }
+ dynstr_trunc(&where, 1);
+ dynstr_append_checked(&where,"))");
+
+ DBUG_PRINT("info",("Dump TS for Tables where: %s",where.str));
+ r= dump_tablespaces(where.str);
+ dynstr_free(&where);
+ return r;
+}
+
+static int dump_tablespaces_for_databases(char** databases)
+{
+ DYNAMIC_STRING where;
+ int r;
+ int i;
+
+ init_dynamic_string_checked(&where, " AND TABLESPACE_NAME IN ("
+ "SELECT DISTINCT TABLESPACE_NAME FROM"
+ " INFORMATION_SCHEMA.PARTITIONS"
+ " WHERE"
+ " TABLE_SCHEMA IN (", 256, 1024);
+
+ for (i=0 ; databases[i]!=NULL ; i++)
+ {
+ char db_name_buff[NAME_LEN*2+3];
+ mysql_real_escape_string(mysql, db_name_buff,
+ databases[i], strlen(databases[i]));
+ dynstr_append_checked(&where, "'");
+ dynstr_append_checked(&where, db_name_buff);
+ dynstr_append_checked(&where, "',");
+ }
+ dynstr_trunc(&where, 1);
+ dynstr_append_checked(&where,"))");
+
+ DBUG_PRINT("info",("Dump TS for DBs where: %s",where.str));
+ r= dump_tablespaces(where.str);
+ dynstr_free(&where);
+ return r;
+}
+
+static int dump_tablespaces(char* ts_where)
+{
+ MYSQL_ROW row;
+ MYSQL_RES *tableres;
+ char buf[FN_REFLEN];
+ DYNAMIC_STRING sqlbuf;
+ int first= 0;
+ /*
+ The following are used for parsing the EXTRA field
+ */
+ char extra_format[]= "UNDO_BUFFER_SIZE=";
+ char *ubs;
+ char *endsemi;
+
+ init_dynamic_string_checked(&sqlbuf,
+ "SELECT LOGFILE_GROUP_NAME,"
+ " FILE_NAME,"
+ " TOTAL_EXTENTS,"
+ " INITIAL_SIZE,"
+ " ENGINE,"
+ " EXTRA"
+ " FROM INFORMATION_SCHEMA.FILES"
+ " WHERE FILE_TYPE = 'UNDO LOG'"
+ " AND FILE_NAME IS NOT NULL",
+ 256, 1024);
+ if(ts_where)
+ {
+ dynstr_append_checked(&sqlbuf,
+ " AND LOGFILE_GROUP_NAME IN ("
+ "SELECT DISTINCT LOGFILE_GROUP_NAME"
+ " FROM INFORMATION_SCHEMA.FILES"
+ " WHERE FILE_TYPE = 'DATAFILE'"
+ );
+ dynstr_append_checked(&sqlbuf, ts_where);
+ dynstr_append_checked(&sqlbuf, ")");
+ }
+ dynstr_append_checked(&sqlbuf,
+ " GROUP BY LOGFILE_GROUP_NAME, FILE_NAME"
+ ", ENGINE"
+ " ORDER BY LOGFILE_GROUP_NAME");
+
+ if (mysql_query(mysql, sqlbuf.str) ||
+ !(tableres = mysql_store_result(mysql)))
+ {
+ if (mysql_errno(mysql) == ER_BAD_TABLE_ERROR ||
+ mysql_errno(mysql) == ER_BAD_DB_ERROR ||
+ mysql_errno(mysql) == ER_UNKNOWN_TABLE)
+ {
+ fprintf(md_result_file,
+ "\n--\n-- Not dumping tablespaces as no INFORMATION_SCHEMA.FILES"
+ " table on this server\n--\n");
+ check_io(md_result_file);
+ return 0;
+ }
+
+ my_printf_error(0, "Error: Couldn't dump tablespaces %s",
+ MYF(0), mysql_error(mysql));
+ return 1;
+ }
+
+ buf[0]= 0;
+ while ((row= mysql_fetch_row(tableres)))
+ {
+ if (strcmp(buf, row[0]) != 0)
+ first= 1;
+ if (first)
+ {
+ if (!opt_xml && opt_comments)
+ {
+ fprintf(md_result_file,"\n--\n-- Logfile group: %s\n--\n", row[0]);
+ check_io(md_result_file);
+ }
+ fprintf(md_result_file, "\nCREATE");
+ }
+ else
+ {
+ fprintf(md_result_file, "\nALTER");
+ }
+ fprintf(md_result_file,
+ " LOGFILE GROUP %s\n"
+ " ADD UNDOFILE '%s'\n",
+ row[0],
+ row[1]);
+ if (first)
+ {
+ ubs= strstr(row[5],extra_format);
+ if(!ubs)
+ break;
+ ubs+= strlen(extra_format);
+ endsemi= strstr(ubs,";");
+ if(endsemi)
+ endsemi[0]= '\0';
+ fprintf(md_result_file,
+ " UNDO_BUFFER_SIZE %s\n",
+ ubs);
+ }
+ fprintf(md_result_file,
+ " INITIAL_SIZE %s\n"
+ " ENGINE=%s;\n",
+ row[3],
+ row[4]);
+ check_io(md_result_file);
+ if (first)
+ {
+ first= 0;
+ strxmov(buf, row[0], NullS);
+ }
+ }
+ dynstr_free(&sqlbuf);
+ init_dynamic_string_checked(&sqlbuf,
+ "SELECT DISTINCT TABLESPACE_NAME,"
+ " FILE_NAME,"
+ " LOGFILE_GROUP_NAME,"
+ " EXTENT_SIZE,"
+ " INITIAL_SIZE,"
+ " ENGINE"
+ " FROM INFORMATION_SCHEMA.FILES"
+ " WHERE FILE_TYPE = 'DATAFILE'",
+ 256, 1024);
+
+ if(ts_where)
+ dynstr_append_checked(&sqlbuf, ts_where);
+
+ dynstr_append_checked(&sqlbuf, " ORDER BY TABLESPACE_NAME, LOGFILE_GROUP_NAME");
+
+ if (mysql_query_with_error_report(mysql, &tableres, sqlbuf.str))
+ return 1;
+
+ buf[0]= 0;
+ while ((row= mysql_fetch_row(tableres)))
+ {
+ if (strcmp(buf, row[0]) != 0)
+ first= 1;
+ if (first)
+ {
+ if (!opt_xml && opt_comments)
+ {
+ fprintf(md_result_file,"\n--\n-- Tablespace: %s\n--\n", row[0]);
+ check_io(md_result_file);
+ }
+ fprintf(md_result_file, "\nCREATE");
+ }
+ else
+ {
+ fprintf(md_result_file, "\nALTER");
+ }
+ fprintf(md_result_file,
+ " TABLESPACE %s\n"
+ " ADD DATAFILE '%s'\n",
+ row[0],
+ row[1]);
+ if (first)
+ {
+ fprintf(md_result_file,
+ " USE LOGFILE GROUP %s\n"
+ " EXTENT_SIZE %s\n",
+ row[2],
+ row[3]);
+ }
+ fprintf(md_result_file,
+ " INITIAL_SIZE %s\n"
+ " ENGINE=%s;\n",
+ row[4],
+ row[5]);
+ check_io(md_result_file);
+ if (first)
+ {
+ first= 0;
+ strxmov(buf, row[0], NullS);
+ }
+ }
+
+ dynstr_free(&sqlbuf);
+ return 0;
+}
+
static int dump_all_databases()
{
MYSQL_ROW row;
@@ -2963,8 +3371,12 @@ static int dump_all_tables_in_db(char *database)
init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024);
for (numrows= 0 ; (table= getTableName(1)) ; numrows++)
{
- dynstr_append_checked(&query, quote_name(table, table_buff, 1));
- dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
+ char *end= strmov(afterdot, table);
+ if (include_table(hash_key,end - hash_key))
+ {
+ dynstr_append_checked(&query, quote_name(table, table_buff, 1));
+ dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
+ }
}
if (numrows && mysql_real_query(mysql, query.str, query.length-1))
DB_error(mysql, "when using LOCK TABLES");
@@ -2990,6 +3402,12 @@ static int dump_all_tables_in_db(char *database)
dump_triggers_for_table(table, database);
}
}
+ if (opt_events && !opt_xml &&
+ mysql_get_server_version(mysql) >= 50106)
+ {
+ DBUG_PRINT("info", ("Dumping events for database %s", database));
+ dump_events_for_db(database);
+ }
if (opt_routines && !opt_xml &&
mysql_get_server_version(mysql) >= 50009)
{
@@ -3118,14 +3536,14 @@ static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root)
static int dump_selected_tables(char *db, char **table_names, int tables)
{
- char table_buff[NAME_LEN*+3];
+ char table_buff[NAME_LEN*2+3];
DYNAMIC_STRING lock_tables_query;
MEM_ROOT root;
char **dump_tables, **pos, **end;
DBUG_ENTER("dump_selected_tables");
if (init_dumping(db, init_dumping_tables))
- return 1;
+ DBUG_RETURN(1);
init_alloc_root(&root, 8192, 0);
if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *))))
@@ -3186,6 +3604,12 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
for (pos= dump_tables; pos < end; pos++)
get_view_structure(*pos, db);
}
+ if (opt_events && !opt_xml &&
+ mysql_get_server_version(mysql) >= 50106)
+ {
+ DBUG_PRINT("info", ("Dumping events for database %s", db));
+ dump_events_for_db(db);
+ }
/* obtain dump of routines (procs/functions) */
if (opt_routines && !opt_xml &&
mysql_get_server_version(mysql) >= 50009)
@@ -3881,16 +4305,27 @@ int main(int argc, char **argv)
if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */
goto err;
+ if (opt_alltspcs)
+ dump_all_tablespaces();
+
if (opt_alldbs)
+ {
+ if (!opt_alltspcs && !opt_notspcs)
+ dump_all_tablespaces();
dump_all_databases();
+ }
else if (argc > 1 && !opt_databases)
{
/* Only one database and selected table(s) */
+ if (!opt_alltspcs && !opt_notspcs)
+ dump_tablespaces_for_tables(*argv, (argv + 1), (argc -1));
dump_selected_tables(*argv, (argv + 1), (argc - 1));
}
else
{
/* One or more databases, all tables */
+ if (!opt_alltspcs && !opt_notspcs)
+ dump_tablespaces_for_databases(argv);
dump_databases(argv);
}
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index e7bf1cfd889..c037da9c0b9 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -24,10 +24,21 @@
** * *
** *************************
*/
-#define IMPORT_VERSION "3.5"
+#define IMPORT_VERSION "3.6"
#include "client_priv.h"
#include "mysql_version.h"
+#ifdef HAVE_LIBPTHREAD
+#include <my_pthread.h>
+#endif
+
+
+/* Global Thread counter */
+uint counter;
+#ifdef HAVE_LIBPTHREAD
+pthread_mutex_t counter_mutex;
+pthread_cond_t count_threshhold;
+#endif
static void db_error_with_table(MYSQL *mysql, char *table);
static void db_error(MYSQL *mysql);
@@ -38,8 +49,8 @@ static char *add_load_option(char *ptr,const char *object,
static my_bool verbose=0,lock_tables=0,ignore_errors=0,opt_delete=0,
replace=0,silent=0,ignore=0,opt_compress=0,
opt_low_priority= 0, tty_password= 0;
-static uint opt_local_file=0;
-static MYSQL mysql_connection;
+static my_bool info_flag= 0;
+static uint opt_use_threads=0, opt_local_file=0;
static char *opt_password=0, *current_user=0,
*current_host=0, *current_db=0, *fields_terminated=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0,
@@ -76,6 +87,8 @@ static struct my_option my_long_options[] =
0, 0, 0},
{"debug",'#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0,
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (gptr*) &info_flag,
+ (gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"delete", 'd', "First delete all rows from table.", (gptr*) &opt_delete,
(gptr*) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"fields-terminated-by", OPT_FTB,
@@ -107,8 +120,9 @@ static struct my_option my_long_options[] =
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"local", 'L', "Read all files through the client.", (gptr*) &opt_local_file,
(gptr*) &opt_local_file, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"lock-tables", 'l', "Lock all tables for write.", (gptr*) &lock_tables,
- (gptr*) &lock_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"lock-tables", 'l', "Lock all tables for write (this disables threads).",
+ (gptr*) &lock_tables, (gptr*) &lock_tables, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
{"low-priority", OPT_LOW_PRIORITY,
"Use LOW_PRIORITY when updating the table.", (gptr*) &opt_low_priority,
(gptr*) &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -137,6 +151,11 @@ static struct my_option my_long_options[] =
(gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include <sslopt-longopts.h>
+ {"use-threads", OPT_USE_THREADS,
+ "Load files in parallel. The argument is the number "
+ "of threads to use for loading data.",
+ (gptr*) &opt_use_threads, (gptr*) &opt_use_threads, 0,
+ GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DONT_ALLOW_USER_CHANGE
{"user", 'u', "User for login if not current user.", (gptr*) &current_user,
(gptr*) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -212,14 +231,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
#endif
case OPT_MYSQL_PROTOCOL:
- {
- if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0)
- {
- fprintf(stderr, "Unknown option to protocol: %s\n", argument);
- exit(1);
- }
+ opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
+ opt->name);
break;
- }
case '#':
DBUG_PUSH(argument ? argument : "d:t:o");
break;
@@ -269,7 +283,7 @@ static int get_options(int *argc, char ***argv)
-static int write_to_table(char *filename, MYSQL *sock)
+static int write_to_table(char *filename, MYSQL *mysql)
{
char tablename[FN_REFLEN], hard_path[FN_REFLEN],
sql_statement[FN_REFLEN*16+256], *end;
@@ -277,7 +291,7 @@ static int write_to_table(char *filename, MYSQL *sock)
DBUG_PRINT("enter",("filename: %s",filename));
fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
- if (! opt_local_file)
+ if (!opt_local_file)
strmov(hard_path,filename);
else
my_load_path(hard_path, filename, NULL); /* filename includes the path */
@@ -286,10 +300,14 @@ static int write_to_table(char *filename, MYSQL *sock)
{
if (verbose)
fprintf(stdout, "Deleting the old data from table %s\n", tablename);
+#ifdef HAVE_SNPRINTF
+ snprintf(sql_statement, FN_REFLEN*16+256, "DELETE FROM %s", tablename);
+#else
sprintf(sql_statement, "DELETE FROM %s", tablename);
- if (mysql_query(sock, sql_statement))
+#endif
+ if (mysql_query(mysql, sql_statement))
{
- db_error_with_table(sock, tablename);
+ db_error_with_table(mysql, tablename);
DBUG_RETURN(1);
}
}
@@ -328,17 +346,17 @@ static int write_to_table(char *filename, MYSQL *sock)
end= strmov(strmov(strmov(end, " ("), opt_columns), ")");
*end= '\0';
- if (mysql_query(sock, sql_statement))
+ if (mysql_query(mysql, sql_statement))
{
- db_error_with_table(sock, tablename);
+ db_error_with_table(mysql, tablename);
DBUG_RETURN(1);
}
if (!silent)
{
- if (mysql_info(sock)) /* If NULL-pointer, print nothing */
+ if (mysql_info(mysql)) /* If NULL-pointer, print nothing */
{
fprintf(stdout, "%s.%s: %s\n", current_db, tablename,
- mysql_info(sock));
+ mysql_info(mysql));
}
}
DBUG_RETURN(0);
@@ -346,7 +364,7 @@ static int write_to_table(char *filename, MYSQL *sock)
-static void lock_table(MYSQL *sock, int tablecount, char **raw_tablename)
+static void lock_table(MYSQL *mysql, int tablecount, char **raw_tablename)
{
DYNAMIC_STRING query;
int i;
@@ -361,72 +379,74 @@ static void lock_table(MYSQL *sock, int tablecount, char **raw_tablename)
dynstr_append(&query, tablename);
dynstr_append(&query, " WRITE,");
}
- if (mysql_real_query(sock, query.str, query.length-1))
- db_error(sock); /* We shall countinue here, if --force was given */
+ if (mysql_real_query(mysql, query.str, query.length-1))
+ db_error(mysql); /* We shall countinue here, if --force was given */
}
-static MYSQL *db_connect(char *host, char *database, char *user, char *passwd)
+static MYSQL *db_connect(char *host, char *database,
+ char *user, char *passwd)
{
- MYSQL *sock;
+ MYSQL *mysql;
if (verbose)
fprintf(stdout, "Connecting to %s\n", host ? host : "localhost");
- mysql_init(&mysql_connection);
+ if (!(mysql= mysql_init(NULL)))
+ return 0;
if (opt_compress)
- mysql_options(&mysql_connection,MYSQL_OPT_COMPRESS,NullS);
+ mysql_options(mysql,MYSQL_OPT_COMPRESS,NullS);
if (opt_local_file)
- mysql_options(&mysql_connection,MYSQL_OPT_LOCAL_INFILE,
+ mysql_options(mysql,MYSQL_OPT_LOCAL_INFILE,
(char*) &opt_local_file);
#ifdef HAVE_OPENSSL
if (opt_use_ssl)
- mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
+ mysql_ssl_set(mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
- mysql_options(&mysql_connection,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+ mysql_options(mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
(char*)&opt_ssl_verify_server_cert);
#endif
if (opt_protocol)
- mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+ mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
#ifdef HAVE_SMEM
if (shared_memory_base_name)
- mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
+ mysql_options(mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
- if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd,
- database,opt_mysql_port,opt_mysql_unix_port,
- 0)))
+ if (!(mysql_real_connect(mysql,host,user,passwd,
+ database,opt_mysql_port,opt_mysql_unix_port,
+ 0)))
{
ignore_errors=0; /* NO RETURN FROM db_error */
- db_error(&mysql_connection);
+ db_error(mysql);
}
- mysql_connection.reconnect= 0;
+ mysql->reconnect= 0;
if (verbose)
fprintf(stdout, "Selecting database %s\n", database);
- if (mysql_select_db(sock, database))
+ if (mysql_select_db(mysql, database))
{
ignore_errors=0;
- db_error(&mysql_connection);
+ db_error(mysql);
}
- return sock;
+ return mysql;
}
-static void db_disconnect(char *host, MYSQL *sock)
+static void db_disconnect(char *host, MYSQL *mysql)
{
if (verbose)
fprintf(stdout, "Disconnecting from %s\n", host ? host : "localhost");
- mysql_close(sock);
+ mysql_close(mysql);
}
-static void safe_exit(int error, MYSQL *sock)
+static void safe_exit(int error, MYSQL *mysql)
{
if (ignore_errors)
return;
- if (sock)
- mysql_close(sock);
+ if (mysql)
+ mysql_close(mysql);
exit(error);
}
@@ -434,8 +454,8 @@ static void safe_exit(int error, MYSQL *sock)
static void db_error_with_table(MYSQL *mysql, char *table)
{
- my_printf_error(0,"Error: %s, when using table: %s",
- MYF(0), mysql_error(mysql), table);
+ my_printf_error(0,"Error: %d, %s, when using table: %s",
+ MYF(0), mysql_errno(mysql), mysql_error(mysql), table);
safe_exit(1, mysql);
}
@@ -443,7 +463,7 @@ static void db_error_with_table(MYSQL *mysql, char *table)
static void db_error(MYSQL *mysql)
{
- my_printf_error(0,"Error: %s", MYF(0), mysql_error(mysql));
+ my_printf_error(0,"Error: %d %s", MYF(0), mysql_errno(mysql), mysql_error(mysql));
safe_exit(1, mysql);
}
@@ -497,13 +517,55 @@ static char *field_escape(char *to,const char *from,uint length)
return to;
}
+int exitcode= 0;
+
+#ifdef HAVE_LIBPTHREAD
+pthread_handler_t worker_thread(void *arg)
+{
+ int error;
+ char *raw_table_name= (char *)arg;
+ MYSQL *mysql= 0;
+
+ if (mysql_thread_init())
+ goto error;
+
+ if (!(mysql= db_connect(current_host,current_db,current_user,opt_password)))
+ {
+ goto error;
+ }
+
+ if (mysql_query(mysql, "/*!40101 set @@character_set_database=binary */;"))
+ {
+ db_error(mysql); /* We shall countinue here, if --force was given */
+ goto error;
+ }
+
+ /*
+ We are not currently catching the error here.
+ */
+ if((error= write_to_table(raw_table_name, mysql)))
+ if (exitcode == 0)
+ exitcode= error;
+
+error:
+ if (mysql)
+ db_disconnect(current_host, mysql);
+
+ pthread_mutex_lock(&counter_mutex);
+ counter--;
+ pthread_cond_signal(&count_threshhold);
+ pthread_mutex_unlock(&counter_mutex);
+ my_thread_end();
+
+ return 0;
+}
+#endif
int main(int argc, char **argv)
{
- int exitcode=0, error=0;
+ int error=0;
char **argv_to_free;
- MYSQL *sock=0;
MY_INIT(argv[0]);
load_defaults("my",load_default_groups,&argc,&argv);
@@ -514,30 +576,89 @@ int main(int argc, char **argv)
free_defaults(argv_to_free);
return(1);
}
- if (!(sock= db_connect(current_host,current_db,current_user,opt_password)))
- {
- free_defaults(argv_to_free);
- return(1); /* purecov: deadcode */
- }
- if (mysql_query(sock, "/*!40101 set @@character_set_database=binary */;"))
+#ifdef HAVE_LIBPTHREAD
+ if (opt_use_threads && !lock_tables)
{
- db_error(sock); /* We shall countinue here, if --force was given */
- return(1);
+ pthread_t mainthread; /* Thread descriptor */
+ pthread_attr_t attr; /* Thread attributes */
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr,
+ PTHREAD_CREATE_DETACHED);
+
+ VOID(pthread_mutex_init(&counter_mutex, NULL));
+ VOID(pthread_cond_init(&count_threshhold, NULL));
+
+ for (counter= 0; *argv != NULL; argv++) /* Loop through tables */
+ {
+ pthread_mutex_lock(&counter_mutex);
+ while (counter == opt_use_threads)
+ {
+ struct timespec abstime;
+
+ set_timespec(abstime, 3);
+ pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
+ }
+ /* Before exiting the lock we set ourselves up for the next thread */
+ counter++;
+ pthread_mutex_unlock(&counter_mutex);
+ /* now create the thread */
+ if (pthread_create(&mainthread, &attr, worker_thread,
+ (void *)*argv) != 0)
+ {
+ pthread_mutex_lock(&counter_mutex);
+ counter--;
+ pthread_mutex_unlock(&counter_mutex);
+ fprintf(stderr,"%s: Could not create thread\n",
+ my_progname);
+ }
+ }
+
+ /*
+ We loop until we know that all children have cleaned up.
+ */
+ pthread_mutex_lock(&counter_mutex);
+ while (counter)
+ {
+ struct timespec abstime;
+
+ set_timespec(abstime, 3);
+ pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
+ }
+ pthread_mutex_unlock(&counter_mutex);
+ VOID(pthread_mutex_destroy(&counter_mutex));
+ VOID(pthread_cond_destroy(&count_threshhold));
+ pthread_attr_destroy(&attr);
}
+ else
+#endif
+ {
+ MYSQL *mysql= 0;
+ if (!(mysql= db_connect(current_host,current_db,current_user,opt_password)))
+ {
+ free_defaults(argv_to_free);
+ return(1); /* purecov: deadcode */
+ }
- if (lock_tables)
- lock_table(sock, argc, argv);
- for (; *argv != NULL; argv++)
- if ((error=write_to_table(*argv, sock)))
- if (exitcode == 0)
- exitcode = error;
- db_disconnect(current_host, sock);
+ if (mysql_query(mysql, "/*!40101 set @@character_set_database=binary */;"))
+ {
+ db_error(mysql); /* We shall countinue here, if --force was given */
+ return(1);
+ }
+
+ if (lock_tables)
+ lock_table(mysql, argc, argv);
+ for (; *argv != NULL; argv++)
+ if ((error= write_to_table(*argv, mysql)))
+ if (exitcode == 0)
+ exitcode= error;
+ db_disconnect(current_host, mysql);
+ }
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
#ifdef HAVE_SMEM
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
#endif
free_defaults(argv_to_free);
- my_end(0);
+ my_end(info_flag ? MY_CHECK_ERROR : 0);
return(exitcode);
}
diff --git a/client/mysqlmanager-pwgen.c b/client/mysqlmanager-pwgen.c
deleted file mode 100644
index 716a1e4bf4e..00000000000
--- a/client/mysqlmanager-pwgen.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* Copyright (C) 2000 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#define MANAGER_PWGEN_VERSION "1.4"
-
-#include <my_global.h>
-#include <m_ctype.h>
-#include <my_sys.h>
-#include <m_string.h>
-#include <mysql_version.h>
-#include <errno.h>
-#include <my_getopt.h>
-#include <md5.h>
-
-const char* outfile=0,*user="root";
-
-static struct my_option my_long_options[] =
-{
- {"output-file", 'o', "Write the output to the file with the given name.",
- (gptr*) &outfile, (gptr*) &outfile, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
- 0, 0},
- {"user", 'u', "Put given user in the password file.", (gptr*) &user,
- (gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"help", '?', "Display this message and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
- 0, 0, 0, 0, 0, 0},
- {"version", 'V', "Display version info.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
- 0, 0, 0, 0},
- {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
-};
-
-static void die(const char* fmt, ...)
-{
- va_list args;
- DBUG_ENTER("die");
- va_start(args, fmt);
- if (fmt)
- {
- fprintf(stderr, "%s: ", my_progname);
- vfprintf(stderr, fmt, args);
- fprintf(stderr, "\n");
- fflush(stderr);
- }
- va_end(args);
- exit(1);
-}
-
-static void print_version(void)
-{
- printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,
- MANAGER_PWGEN_VERSION,
- MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
-}
-
-void usage()
-{
- print_version();
- printf("MySQL AB, by Sasha\n");
- printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
- printf("Generates a password file to be used by mysqltest.\n\n");
- printf("Usage: %s [OPTIONS]\n", my_progname);
- my_print_help(my_long_options);
- my_print_variables(my_long_options);
-}
-
-static my_bool
-get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
- char *argument __attribute__((unused)))
-{
- switch (optid) {
- case '?':
- usage();
- exit(0);
- case 'V':
- print_version();
- exit(0);
- }
- return 0;
-}
-
-
-int parse_args(int argc, char** argv)
-{
- int ho_error;
-
- if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
- exit(ho_error);
-
- return 0;
-}
-
-void get_pass(char* pw, int len)
-{
- FILE* fp;
- char* pw_end=pw+len;
- /*
- /dev/random is more secure than rand() because the seed is easy to
- predict, so we resort to rand() only if /dev/random is not available
- */
- if ((fp=fopen("/dev/random","r")))
- {
- fread(pw,len,1,fp);
- fclose(fp);
- while (pw<pw_end)
- {
- char tmp= 'a'+((uint)*pw % 26);
- *pw++= tmp;
- }
- }
- else
- {
- srand(time(NULL));
- while (pw<pw_end)
- {
- char tmp= 'a'+((uint)*pw % 26);
- *pw++= tmp;
- }
- }
- *pw_end=0;
-}
-
-
-int main(int argc, char** argv)
-{
- FILE* fp;
- my_MD5_CTX context;
- uchar digest[16];
- char pw[17];
- uint i;
-
- MY_INIT(argv[0]);
- parse_args(argc,argv);
- if (!outfile)
- die("Missing --output-file");
-
- if (!(fp=fopen(outfile,"w")))
- die("Could not open '%s'(errno=%d)",outfile,errno);
- get_pass(pw,sizeof(pw)-1);
- my_MD5Init(&context);
- my_MD5Update(&context,(uchar*) pw,sizeof(pw)-1);
- my_MD5Final(digest,&context);
- fprintf(fp,"%s:",user);
- for (i=0;i<sizeof(digest);i++)
- fprintf(fp,"%02x",digest[i]);
- fprintf(fp,"\n");
- fclose(fp);
- printf("%s\n",pw);
- return 0;
-}
diff --git a/client/mysqlmanagerc.c b/client/mysqlmanagerc.c
deleted file mode 100644
index 1fdedab97fb..00000000000
--- a/client/mysqlmanagerc.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Copyright (C) 2000 MySQL AB
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#define MANAGER_CLIENT_VERSION "1.4"
-
-#include <my_global.h>
-#include <mysql.h>
-#include <mysql_version.h>
-#include <mysqld_error.h>
-#include <my_sys.h>
-#include <m_string.h>
-#include <my_getopt.h>
-#include <stdarg.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#ifndef MYSQL_MANAGER_PORT
-#define MYSQL_MANAGER_PORT 9305
-#endif
-
-static void die(const char* fmt, ...);
-
-const char* user="root",*host="localhost";
-char* pass=0;
-my_bool quiet=0;
-uint port=MYSQL_MANAGER_PORT;
-static const char *load_default_groups[]= { "mysqlmanagerc",0 };
-char** default_argv;
-MYSQL_MANAGER *manager;
-FILE* fp, *fp_out;
-
-static struct my_option my_long_options[] =
-{
- {"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"user", 'u', "User for login.", (gptr*) &user, (gptr*) &user, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"password", 'p', "Password to use when connecting to server.",
- 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
- {"port", 'P', "Port number to use for connection.", (gptr*) &port,
- (gptr*) &port, 0, GET_UINT, REQUIRED_ARG, MYSQL_MANAGER_PORT, 0, 0, 0, 0,
- 0},
- {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
- 0, 0, 0, 0, 0, 0},
- {"version", 'V', "Output version information and exit.", 0, 0, 0,
- GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"quiet", 'q', "Suppress all normal output.", (gptr*) &quiet, (gptr*) &quiet,
- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
-};
-
-static void die(const char* fmt, ...)
-{
- va_list args;
- DBUG_ENTER("die");
- va_start(args, fmt);
- if (fmt)
- {
- fprintf(stderr, "%s: ", my_progname);
- vfprintf(stderr, fmt, args);
- fprintf(stderr, "\n");
- fflush(stderr);
- }
- va_end(args);
- exit(1);
-}
-
-static void print_version(void)
-{
- printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,
- MANAGER_CLIENT_VERSION,
- MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
-}
-
-void usage()
-{
- print_version();
- printf("MySQL AB, by Sasha\n");
- printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
- printf("Command-line client for MySQL manager daemon.\n\n");
- printf("Usage: %s [OPTIONS] < command_file\n", my_progname);
- my_print_help(my_long_options);
- printf(" --no-defaults Don't read default options from any options file.\n");
- my_print_variables(my_long_options);
-}
-
-
-static my_bool
-get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
- char *argument)
-{
- my_bool tty_password=0;
-
- switch (optid) {
- case 'p':
- if (argument)
- {
- my_free(pass, MYF(MY_ALLOW_ZERO_PTR));
- pass= my_strdup(argument, MYF(MY_FAE));
- while (*argument) *argument++= 'x'; /* Destroy argument */
- }
- else
- tty_password=1;
- break;
- case 'V':
- print_version();
- exit(0);
- case '?':
- usage();
- exit(0);
- }
- return 0;
-}
-
-
-int parse_args(int argc, char **argv)
-{
- int ho_error;
-
- load_defaults("my",load_default_groups,&argc,&argv);
- default_argv= argv;
-
- if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
- exit(ho_error);
-
- return 0;
-}
-
-
-int main(int argc, char** argv)
-{
- MY_INIT(argv[0]);
- fp=stdin;
- fp_out=stdout;
- parse_args(argc,argv);
- if (!(manager=mysql_manager_init(0)))
- die("Failed in mysql_manager_init()");
- if (!mysql_manager_connect(manager,host,user,pass,port))
- die("Could not connect to MySQL manager: %s (%d)",manager->last_error,
- manager->last_errno);
- for (;!feof(fp);)
- {
- char buf[4096];
- if (!fgets(buf,sizeof(buf),fp))
- break;
- if (!quiet)
- fprintf(fp_out,"<<%s",buf);
- if (mysql_manager_command(manager,buf,strlen(buf)))
- die("Error in command: %s (%d)",manager->last_error,manager->last_errno);
- while (!manager->eof)
- {
- if (mysql_manager_fetch_line(manager,buf,sizeof(buf)))
- die("Error fetching result line: %s (%d)", manager->last_error,
- manager->last_errno);
- if (!quiet)
- fprintf(fp_out,">>%s\n",buf);
- }
- }
- mysql_manager_close(manager);
- return 0;
-}
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index 5be01cc5a52..0c6a6229964 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -15,7 +15,7 @@
/* Show databases, tables or columns */
-#define SHOW_VERSION "9.5"
+#define SHOW_VERSION "9.6"
#include "client_priv.h"
#include <my_sys.h>
@@ -27,8 +27,8 @@
#include <sslopt-vars.h>
static my_string host=0,opt_password=0,user=0;
-static my_bool opt_show_keys= 0, opt_compress= 0, opt_count=0, opt_status= 0,
- tty_password= 0, opt_table_type= 0;
+static my_bool opt_show_keys= 0, opt_compress= 0, opt_count=0, opt_status= 0;
+static my_bool tty_password= 0, opt_table_type= 0, info_flag= 0;
static uint opt_verbose=0;
static char *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
@@ -128,8 +128,7 @@ int main(int argc, char **argv)
}
mysql.reconnect= 1;
- switch (argc)
- {
+ switch (argc) {
case 0: error=list_dbs(&mysql,wild); break;
case 1:
if (opt_status)
@@ -150,7 +149,7 @@ int main(int argc, char **argv)
#ifdef HAVE_SMEM
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
#endif
- my_end(0);
+ my_end(info_flag ? MY_CHECK_ERROR : 0);
exit(error ? 1 : 0);
return 0; /* No compiler warnings */
}
@@ -176,6 +175,8 @@ static struct my_option my_long_options[] =
0, 0, 0},
{"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (gptr*) &info_flag,
+ (gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
0, 0, 0, 0, 0, 0},
{"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0, GET_STR,
@@ -286,14 +287,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
#endif
break;
case OPT_MYSQL_PROTOCOL:
- {
- if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0)
- {
- fprintf(stderr, "Unknown option to protocol: %s\n", argument);
- exit(1);
- }
+ opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
+ opt->name);
break;
- }
case '#':
DBUG_PUSH(argument ? argument : "d:t:o");
break;
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
new file mode 100644
index 00000000000..0335922881a
--- /dev/null
+++ b/client/mysqlslap.c
@@ -0,0 +1,2104 @@
+/* Copyright (C) 2005 MySQL AB
+
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ original idea: Brian Aker via playing with ab for too many years
+ coded by: Patrick Galbraith
+*/
+
+
+/*
+ MySQL Slap
+
+ A simple program designed to work as if multiple clients querying the database,
+ then reporting the timing of each stage.
+
+ MySQL slap runs three stages:
+ 1) Create schema,table, and optionally any SP or data you want to beign
+ the test with. (single client)
+ 2) Load test (many clients)
+ 3) Cleanup (disconnection, drop table if specified, single client)
+
+ Examples:
+
+ Supply your own create and query SQL statements, with 50 clients
+ querying (200 selects for each):
+
+ mysqlslap --create="CREATE TABLE A (a int);INSERT INTO A (23)" \
+ --query="SELECT * FROM A" --concurrency=50 --iterations=200
+
+ Let the program build the query SQL statement with a table of two int
+ columns, three varchar columns, five clients querying (20 times each),
+ don't create the table or insert the data (using the previous test's
+ schema and data):
+
+ mysqlslap --concurrency=5 --iterations=20 \
+ --number-int-cols=2 --number-char-cols=3 \
+ --auto-generate-sql
+
+ Tell the program to load the create, insert and query SQL statements from
+ the specified files, where the create.sql file has multiple table creation
+ statements delimited by ';' and multiple insert statements delimited by ';'.
+ The --query file will have multiple queries delimited by ';', run all the
+ load statements, and then run all the queries in the query file
+ with five clients (five times each):
+
+ mysqlslap --concurrency=5 \
+ --iterations=5 --query=query.sql --create=create.sql \
+ --delimiter=";"
+
+TODO:
+ Add language for better tests
+ String length for files and those put on the command line are not
+ setup to handle binary data.
+ More stats
+ Break up tests and run them on multiple hosts at once.
+ Allow output to be fed into a database directly.
+
+*/
+
+#define SHOW_VERSION "0.9"
+
+#define HUGE_STRING_LENGTH 8196
+#define RAND_STRING_SIZE 126
+
+/* Types */
+#define SELECT_TYPE 0
+#define UPDATE_TYPE 1
+#define INSERT_TYPE 2
+#define UPDATE_TYPE_REQUIRES_PREFIX 3
+#define CREATE_TABLE_TYPE 4
+#define SELECT_TYPE_REQUIRES_PREFIX 5
+
+#include "client_priv.h"
+#include <mysqld_error.h>
+#include <my_dir.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <sslopt-vars.h>
+#include <sys/types.h>
+#ifndef __WIN__
+#include <sys/wait.h>
+#endif
+#include <ctype.h>
+
+#ifdef __WIN__
+#define srandom srand
+#define random rand
+#define snprintf _snprintf
+#endif
+
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name=0;
+#endif
+
+/* Global Thread counter */
+uint thread_counter;
+pthread_mutex_t counter_mutex;
+pthread_cond_t count_threshhold;
+uint master_wakeup;
+pthread_mutex_t sleeper_mutex;
+pthread_cond_t sleep_threshhold;
+
+static char **defaults_argv;
+
+char **primary_keys;
+unsigned long long primary_keys_number_of;
+
+static char *host= NULL, *opt_password= NULL, *user= NULL,
+ *user_supplied_query= NULL,
+ *user_supplied_pre_statements= NULL,
+ *user_supplied_post_statements= NULL,
+ *default_engine= NULL,
+ *opt_mysql_unix_port= NULL;
+
+const char *delimiter= "\n";
+
+const char *create_schema_string= "mysqlslap";
+
+static my_bool opt_preserve;
+
+static my_bool opt_only_print= FALSE;
+
+static my_bool opt_compress= FALSE, tty_password= FALSE,
+ opt_silent= FALSE,
+ auto_generate_sql_autoincrement= FALSE,
+ auto_generate_sql_guid_primary= FALSE,
+ auto_generate_sql= FALSE;
+const char *auto_generate_sql_type= "mixed";
+
+static unsigned long connect_flags= CLIENT_MULTI_RESULTS;
+
+static int verbose, delimiter_length;
+const char *num_int_cols_opt;
+const char *num_char_cols_opt;
+/* Yes, we do set defaults here */
+static unsigned int num_int_cols= 1;
+static unsigned int num_char_cols= 1;
+static unsigned int num_int_cols_index= 0;
+static unsigned int num_char_cols_index= 0;
+
+static unsigned int iterations;
+static char *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
+static ulonglong actual_queries= 0;
+static ulonglong auto_actual_queries;
+static ulonglong auto_generate_sql_unique_write_number;
+static ulonglong auto_generate_sql_unique_query_number;
+static unsigned int auto_generate_sql_secondary_indexes;
+static ulonglong num_of_query;
+static ulonglong auto_generate_sql_number;
+const char *concurrency_str= NULL;
+static char *create_string;
+uint *concurrency;
+
+const char *default_dbug_option="d:t:o,/tmp/mysqlslap.trace";
+const char *opt_csv_str;
+File csv_file;
+
+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 };
+
+typedef struct statement statement;
+
+struct statement {
+ char *string;
+ size_t length;
+ unsigned char type;
+ char *option;
+ size_t option_length;
+ statement *next;
+};
+
+typedef struct option_string option_string;
+
+struct option_string {
+ char *string;
+ size_t length;
+ char *option;
+ size_t option_length;
+ option_string *next;
+};
+
+typedef struct stats stats;
+
+struct stats {
+ long int timing;
+ uint users;
+ unsigned long long rows;
+};
+
+typedef struct thread_context thread_context;
+
+struct thread_context {
+ statement *stmt;
+ ulonglong limit;
+};
+
+typedef struct conclusions conclusions;
+
+struct conclusions {
+ char *engine;
+ long int avg_timing;
+ long int max_timing;
+ long int min_timing;
+ uint users;
+ unsigned long long avg_rows;
+ /* The following are not used yet */
+ unsigned long long max_rows;
+ unsigned long long min_rows;
+};
+
+static option_string *engine_options= NULL;
+static statement *pre_statements= NULL;
+static statement *post_statements= NULL;
+static statement *create_statements= NULL,
+ *query_statements= NULL;
+
+/* Prototypes */
+void print_conclusions(conclusions *con);
+void print_conclusions_csv(conclusions *con);
+void generate_stats(conclusions *con, option_string *eng, stats *sptr);
+uint parse_comma(const char *string, uint **range);
+uint parse_delimiter(const char *script, statement **stmt, char delm);
+uint parse_option(const char *origin, option_string **stmt, char delm);
+static int drop_schema(MYSQL *mysql, const char *db);
+uint get_random_string(char *buf);
+static statement *build_table_string(void);
+static statement *build_insert_string(void);
+static statement *build_update_string(void);
+static statement * build_select_string(my_bool key);
+static int generate_primary_key_list(MYSQL *mysql, option_string *engine_stmt);
+static int drop_primary_key_list(void);
+static int create_schema(MYSQL *mysql, const char *db, statement *stmt,
+ option_string *engine_stmt);
+static int run_scheduler(stats *sptr, statement *stmts, uint concur,
+ ulonglong limit);
+pthread_handler_t run_task(void *p);
+void statement_cleanup(statement *stmt);
+void option_cleanup(option_string *stmt);
+void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr);
+static int run_statements(MYSQL *mysql, statement *stmt);
+
+static const char ALPHANUMERICS[]=
+ "0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz";
+
+#define ALPHANUMERICS_SIZE (sizeof(ALPHANUMERICS)-1)
+
+
+static long int timedif(struct timeval a, struct timeval b)
+{
+ register int us, s;
+
+ us = a.tv_usec - b.tv_usec;
+ us /= 1000;
+ s = a.tv_sec - b.tv_sec;
+ s *= 1000;
+ return s + us;
+}
+
+#ifdef __WIN__
+static int gettimeofday(struct timeval *tp, void *tzp)
+{
+ unsigned int ticks;
+ ticks= GetTickCount();
+ tp->tv_usec= ticks*1000;
+ tp->tv_sec= ticks/1000;
+
+ return 0;
+}
+#endif
+
+int main(int argc, char **argv)
+{
+ MYSQL mysql;
+ option_string *eptr;
+
+ MY_INIT(argv[0]);
+
+ load_defaults("my",load_default_groups,&argc,&argv);
+ defaults_argv=argv;
+ if (get_options(&argc,&argv))
+ {
+ free_defaults(defaults_argv);
+ my_end(0);
+ exit(1);
+ }
+
+ /* Seed the random number generator if we will be using it. */
+ if (auto_generate_sql)
+ srandom((uint)time(NULL));
+
+ /* globals? Yes, so we only have to run strlen once */
+ delimiter_length= strlen(delimiter);
+
+ if (argc > 2)
+ {
+ fprintf(stderr,"%s: Too many arguments\n",my_progname);
+ free_defaults(defaults_argv);
+ my_end(0);
+ exit(1);
+ }
+ mysql_init(&mysql);
+ if (opt_compress)
+ mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
+#ifdef HAVE_OPENSSL
+ if (opt_use_ssl)
+ mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
+ opt_ssl_capath, opt_ssl_cipher);
+#endif
+ if (opt_protocol)
+ mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+#ifdef HAVE_SMEM
+ if (shared_memory_base_name)
+ mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
+#endif
+ mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
+
+ if (!opt_only_print)
+ {
+ if (!(mysql_real_connect(&mysql, host, user, opt_password,
+ NULL, opt_mysql_port,
+ opt_mysql_unix_port, connect_flags)))
+ {
+ fprintf(stderr,"%s: Error when connecting to server: %s\n",
+ my_progname,mysql_error(&mysql));
+ free_defaults(defaults_argv);
+ my_end(0);
+ exit(1);
+ }
+ }
+
+ VOID(pthread_mutex_init(&counter_mutex, NULL));
+ VOID(pthread_cond_init(&count_threshhold, NULL));
+ VOID(pthread_mutex_init(&sleeper_mutex, NULL));
+ VOID(pthread_cond_init(&sleep_threshhold, NULL));
+
+ /* Main iterations loop */
+ eptr= engine_options;
+ do
+ {
+ /* For the final stage we run whatever queries we were asked to run */
+ uint *current;
+
+ if (verbose >= 2)
+ printf("Starting Concurrency Test\n");
+
+ if (*concurrency)
+ {
+ for (current= concurrency; current && *current; current++)
+ concurrency_loop(&mysql, *current, eptr);
+ }
+ else
+ {
+ uint infinite= 1;
+ do {
+ concurrency_loop(&mysql, infinite, eptr);
+ }
+ while (infinite++);
+ }
+
+ if (!opt_preserve)
+ drop_schema(&mysql, create_schema_string);
+
+ } while (eptr ? (eptr= eptr->next) : 0);
+
+ VOID(pthread_mutex_destroy(&counter_mutex));
+ VOID(pthread_cond_destroy(&count_threshhold));
+ VOID(pthread_mutex_destroy(&sleeper_mutex));
+ VOID(pthread_cond_destroy(&sleep_threshhold));
+
+ if (!opt_only_print)
+ mysql_close(&mysql); /* Close & free connection */
+
+ /* now free all the strings we created */
+ if (opt_password)
+ my_free((gptr)opt_password, MYF(0));
+
+ my_free((gptr)concurrency, MYF(0));
+
+ statement_cleanup(create_statements);
+ statement_cleanup(query_statements);
+ statement_cleanup(pre_statements);
+ statement_cleanup(post_statements);
+ option_cleanup(engine_options);
+
+#ifdef HAVE_SMEM
+ if (shared_memory_base_name)
+ my_free((gptr)shared_memory_base_name, MYF(MY_ALLOW_ZERO_PTR));
+#endif
+ free_defaults(defaults_argv);
+ my_end(0);
+
+ return 0;
+}
+
+void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr)
+{
+ unsigned int x;
+ stats *head_sptr;
+ stats *sptr;
+ conclusions conclusion;
+ unsigned long long client_limit;
+
+ head_sptr= (stats *)my_malloc(sizeof(stats) * iterations,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+
+ bzero(&conclusion, sizeof(conclusions));
+
+ if (auto_actual_queries)
+ client_limit= auto_actual_queries;
+ else if (num_of_query)
+ client_limit= num_of_query / current;
+ else
+ client_limit= actual_queries;
+
+ for (x= 0, sptr= head_sptr; x < iterations; x++, sptr++)
+ {
+ /*
+ We might not want to load any data, such as when we are calling
+ a stored_procedure that doesn't use data, or we know we already have
+ data in the table.
+ */
+ if (!opt_preserve)
+ drop_schema(mysql, create_schema_string);
+
+ /* First we create */
+ if (create_statements)
+ create_schema(mysql, create_schema_string, create_statements, eptr);
+
+ /*
+ If we generated GUID we need to build a list of them from creation that
+ we can later use.
+ */
+ if (verbose >= 2)
+ printf("Generating primary key list\n");
+ if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
+ generate_primary_key_list(mysql, eptr);
+
+ if (pre_statements)
+ run_statements(mysql, pre_statements);
+
+ run_scheduler(sptr, query_statements, current, client_limit);
+
+ if (post_statements)
+ run_statements(mysql, post_statements);
+
+ /* We are finished with this run */
+ if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
+ drop_primary_key_list();
+ }
+
+ if (verbose >= 2)
+ printf("Generating stats\n");
+
+ generate_stats(&conclusion, eptr, head_sptr);
+
+ if (!opt_silent)
+ print_conclusions(&conclusion);
+ if (opt_csv_str)
+ print_conclusions_csv(&conclusion);
+
+ my_free((gptr)head_sptr, MYF(0));
+
+}
+
+
+static struct my_option my_long_options[] =
+{
+ {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"auto-generate-sql", 'a',
+ "Generate SQL where not supplied by file or command line.",
+ (gptr*) &auto_generate_sql, (gptr*) &auto_generate_sql,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"auto-generate-sql-add-autoincrement", OPT_SLAP_AUTO_GENERATE_ADD_AUTO,
+ "Add autoincrement to auto-generated tables.",
+ (gptr*) &auto_generate_sql_autoincrement,
+ (gptr*) &auto_generate_sql_autoincrement,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"auto-generate-sql-execute-number", OPT_SLAP_AUTO_GENERATE_EXECUTE_QUERIES,
+ "Set this number to generate a set number of queries to run.\n",
+ (gptr*) &auto_actual_queries, (gptr*) &auto_actual_queries,
+ 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"auto-generate-sql-guid-primary", OPT_SLAP_AUTO_GENERATE_GUID_PRIMARY,
+ "Add GUID based primary keys to auto-generated tables.",
+ (gptr*) &auto_generate_sql_guid_primary,
+ (gptr*) &auto_generate_sql_guid_primary,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"auto-generate-sql-load-type", OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE,
+ "Load types are mixed, update, write, key, or read. Default is mixed\n",
+ (gptr*) &auto_generate_sql_type, (gptr*) &auto_generate_sql_type,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"auto-generate-sql-secondary-indexes",
+ OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES,
+ "Number of secondary indexes to add auto-generated tables.",
+ (gptr*) &auto_generate_sql_secondary_indexes,
+ (gptr*) &auto_generate_sql_secondary_indexes, 0,
+ GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"auto-generate-sql-unique-query-number",
+ OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM,
+ "Number of unique queries auto tests",
+ (gptr*) &auto_generate_sql_unique_query_number,
+ (gptr*) &auto_generate_sql_unique_query_number,
+ 0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
+ {"auto-generate-sql-unique-write-number",
+ OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM,
+ "Number of unique queries for auto-generate-sql-write-number",
+ (gptr*) &auto_generate_sql_unique_write_number,
+ (gptr*) &auto_generate_sql_unique_write_number,
+ 0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
+ {"auto-generate-sql-write-number", OPT_SLAP_AUTO_GENERATE_WRITE_NUM,
+ "Number of rows to insert to used in read and write loads (default is 100).\n",
+ (gptr*) &auto_generate_sql_number, (gptr*) &auto_generate_sql_number,
+ 0, GET_ULL, REQUIRED_ARG, 100, 0, 0, 0, 0, 0},
+ {"compress", 'C', "Use compression in server/client protocol.",
+ (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
+ {"concurrency", 'c', "Number of clients to simulate for query to run.",
+ (gptr*) &concurrency_str, (gptr*) &concurrency_str, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"create", OPT_SLAP_CREATE_STRING, "File or string to use create tables.",
+ (gptr*) &create_string, (gptr*) &create_string, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"create-schema", OPT_CREATE_SLAP_SCHEMA, "Schema to run tests in.",
+ (gptr*) &create_schema_string, (gptr*) &create_schema_string, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"csv", OPT_SLAP_CSV,
+ "Generate CSV output to named file or to stdout if no file is named.",
+ (gptr*) &opt_csv_str, (gptr*) &opt_csv_str, 0, GET_STR,
+ OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
+ (gptr*) &default_dbug_option, (gptr*) &default_dbug_option, 0, GET_STR,
+ OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"delimiter", 'F',
+ "Delimiter to use in SQL statements supplied in file or command line.",
+ (gptr*) &delimiter, (gptr*) &delimiter, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"engine", 'e', "Storage engine to use for creating the table.",
+ (gptr*) &default_engine, (gptr*) &default_engine, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"iterations", 'i', "Number of times too run the tests.", (gptr*) &iterations,
+ (gptr*) &iterations, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
+ {"number-char-cols", 'x',
+ "Number of VARCHAR columns to create table with if specifying --auto-generate-sql ",
+ (gptr*) &num_char_cols_opt, (gptr*) &num_char_cols_opt, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"number-int-cols", 'y',
+ "Number of INT columns to create table with if specifying --auto-generate-sql.",
+ (gptr*) &num_int_cols_opt, (gptr*) &num_int_cols_opt, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"number-of-queries", OPT_MYSQL_NUMBER_OF_QUERY,
+ "Limit each client to this number of queries (this is not exact).",
+ (gptr*) &num_of_query, (gptr*) &num_of_query, 0,
+ GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"only-print", OPT_MYSQL_ONLY_PRINT,
+ "This causes mysqlslap to not connect to the databases, but instead print "
+ "out what it would have done instead.",
+ (gptr*) &opt_only_print, (gptr*) &opt_only_print, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's "
+ "asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef __WIN__
+ {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
+ (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
+ 0},
+ {"post-query", OPT_SLAP_POST_QUERY,
+ "Query to run or file containing query to run after executing.",
+ (gptr*) &user_supplied_post_statements,
+ (gptr*) &user_supplied_post_statements,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"pre-query", OPT_SLAP_PRE_QUERY,
+ "Query to run or file containing query to run before executing.",
+ (gptr*) &user_supplied_pre_statements,
+ (gptr*) &user_supplied_pre_statements,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"preserve-schema", OPT_MYSQL_PRESERVE_SCHEMA,
+ "Preserve the schema from the mysqlslap run, this happens unless "
+ "--auto-generate-sql or --create are used.",
+ (gptr*) &opt_preserve, (gptr*) &opt_preserve, 0, GET_BOOL,
+ NO_ARG, TRUE, 0, 0, 0, 0, 0},
+ {"protocol", OPT_MYSQL_PROTOCOL,
+ "The protocol of connection (tcp,socket,pipe,memory).",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"query", 'q', "Query to run or file containing query to run.",
+ (gptr*) &user_supplied_query, (gptr*) &user_supplied_query,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SMEM
+ {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
+ "Base name of shared memory.", (gptr*) &shared_memory_base_name,
+ (gptr*) &shared_memory_base_name, 0, GET_STR_ALLOC, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
+#endif
+ {"silent", 's', "Run program in silent mode - no output.",
+ (gptr*) &opt_silent, (gptr*) &opt_silent, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection.",
+ (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#include <sslopt-longopts.h>
+#ifndef DONT_ALLOW_USER_CHANGE
+ {"user", 'u', "User for login if not current user.", (gptr*) &user,
+ (gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+ {"verbose", 'v',
+ "More verbose output; You can use this multiple times to get even more "
+ "verbose output.", (gptr*) &verbose, (gptr*) &verbose, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+
+#include <help_start.h>
+
+static void print_version(void)
+{
+ printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,SHOW_VERSION,
+ MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+
+
+static void usage(void)
+{
+ print_version();
+ puts("Copyright (C) 2005 MySQL 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("Run a query multiple times against the server\n");
+ printf("Usage: %s [OPTIONS]\n",my_progname);
+ print_defaults("my",load_default_groups);
+ my_print_help(my_long_options);
+}
+
+#include <help_end.h>
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ DBUG_ENTER("get_one_option");
+ switch(optid) {
+#ifdef __NETWARE__
+ case OPT_AUTO_CLOSE:
+ setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
+ break;
+#endif
+ case 'v':
+ verbose++;
+ break;
+ case 'p':
+ if (argument)
+ {
+ char *start= argument;
+ my_free((gptr)opt_password, MYF(MY_ALLOW_ZERO_PTR));
+ opt_password= my_strdup(argument,MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1]= 0; /* Cut length of argument */
+ tty_password= 0;
+ }
+ else
+ tty_password= 1;
+ break;
+ case 'W':
+#ifdef __WIN__
+ opt_protocol= MYSQL_PROTOCOL_PIPE;
+#endif
+ break;
+ case OPT_MYSQL_PROTOCOL:
+ opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
+ opt->name);
+ break;
+ case '#':
+ DBUG_PUSH(argument ? argument : default_dbug_option);
+ break;
+#include <sslopt-case.h>
+ case 'V':
+ print_version();
+ exit(0);
+ break;
+ case '?':
+ case 'I': /* Info */
+ usage();
+ exit(0);
+ }
+ DBUG_RETURN(0);
+}
+
+
+uint
+get_random_string(char *buf)
+{
+ char *buf_ptr= buf;
+ int x;
+ DBUG_ENTER("get_random_string");
+ for (x= RAND_STRING_SIZE; x > 0; x--)
+ *buf_ptr++= ALPHANUMERICS[random() % ALPHANUMERICS_SIZE];
+ DBUG_RETURN(buf_ptr - buf);
+}
+
+
+/*
+ build_table_string
+
+ This function builds a create table query if the user opts to not supply
+ a file or string containing a create table statement
+*/
+static statement *
+build_table_string(void)
+{
+ char buf[HUGE_STRING_LENGTH];
+ unsigned int col_count;
+ statement *ptr;
+ DYNAMIC_STRING table_string;
+ DBUG_ENTER("build_table_string");
+
+ DBUG_PRINT("info", ("num int cols %u num char cols %u",
+ num_int_cols, num_char_cols));
+
+ init_dynamic_string(&table_string, "", 1024, 1024);
+
+ dynstr_append(&table_string, "CREATE TABLE `t1` (");
+
+ if (auto_generate_sql_autoincrement)
+ {
+ dynstr_append(&table_string, "id serial");
+
+ if (num_int_cols || num_char_cols)
+ dynstr_append(&table_string, ",");
+ }
+
+ if (auto_generate_sql_guid_primary)
+ {
+ dynstr_append(&table_string, "id varchar(32) primary key");
+
+ if (num_int_cols || num_char_cols || auto_generate_sql_guid_primary)
+ dynstr_append(&table_string, ",");
+ }
+
+ if (auto_generate_sql_secondary_indexes)
+ {
+ unsigned int count;
+
+ for (count= 0; count < auto_generate_sql_secondary_indexes; count++)
+ {
+ if (count) /* Except for the first pass we add a comma */
+ dynstr_append(&table_string, ",");
+
+ if (snprintf(buf, HUGE_STRING_LENGTH, "id%d varchar(32) unique key", count)
+ > HUGE_STRING_LENGTH)
+ {
+ fprintf(stderr, "Memory Allocation error in create table\n");
+ exit(1);
+ }
+ dynstr_append(&table_string, buf);
+ }
+
+ if (num_int_cols || num_char_cols)
+ dynstr_append(&table_string, ",");
+ }
+
+ if (num_int_cols)
+ for (col_count= 1; col_count <= num_int_cols; col_count++)
+ {
+ if (num_int_cols_index)
+ {
+ if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d INT(32), INDEX(intcol%d)",
+ col_count, col_count) > HUGE_STRING_LENGTH)
+ {
+ fprintf(stderr, "Memory Allocation error in create table\n");
+ exit(1);
+ }
+ }
+ else
+ {
+ if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d INT(32) ", col_count)
+ > HUGE_STRING_LENGTH)
+ {
+ fprintf(stderr, "Memory Allocation error in create table\n");
+ exit(1);
+ }
+ }
+ dynstr_append(&table_string, buf);
+
+ if (col_count < num_int_cols || num_char_cols > 0)
+ dynstr_append(&table_string, ",");
+ }
+
+ if (num_char_cols)
+ for (col_count= 1; col_count <= num_char_cols; col_count++)
+ {
+ if (num_char_cols_index)
+ {
+ if (snprintf(buf, HUGE_STRING_LENGTH,
+ "charcol%d VARCHAR(128), INDEX(charcol%d) ",
+ col_count, col_count) > HUGE_STRING_LENGTH)
+ {
+ fprintf(stderr, "Memory Allocation error in creating table\n");
+ exit(1);
+ }
+ }
+ else
+ {
+ if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d VARCHAR(128)",
+ col_count) > HUGE_STRING_LENGTH)
+ {
+ fprintf(stderr, "Memory Allocation error in creating table\n");
+ exit(1);
+ }
+ }
+ dynstr_append(&table_string, buf);
+
+ if (col_count < num_char_cols)
+ dynstr_append(&table_string, ",");
+ }
+
+ dynstr_append(&table_string, ")");
+ ptr= (statement *)my_malloc(sizeof(statement),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ ptr->string = (char *)my_malloc(table_string.length+1,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ ptr->length= table_string.length+1;
+ ptr->type= CREATE_TABLE_TYPE;
+ strmov(ptr->string, table_string.str);
+ dynstr_free(&table_string);
+ DBUG_RETURN(ptr);
+}
+
+/*
+ build_update_string()
+
+ This function builds insert statements when the user opts to not supply
+ an insert file or string containing insert data
+*/
+static statement *
+build_update_string(void)
+{
+ char buf[HUGE_STRING_LENGTH];
+ unsigned int col_count;
+ statement *ptr;
+ DYNAMIC_STRING update_string;
+ DBUG_ENTER("build_update_string");
+
+ init_dynamic_string(&update_string, "", 1024, 1024);
+
+ dynstr_append(&update_string, "UPDATE t1 SET ");
+
+ if (num_int_cols)
+ for (col_count= 1; col_count <= num_int_cols; col_count++)
+ {
+ if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d = %ld", col_count,
+ random()) > HUGE_STRING_LENGTH)
+ {
+ fprintf(stderr, "Memory Allocation error in creating update\n");
+ exit(1);
+ }
+ dynstr_append(&update_string, buf);
+
+ if (col_count < num_int_cols || num_char_cols > 0)
+ dynstr_append_mem(&update_string, ",", 1);
+ }
+
+ if (num_char_cols)
+ for (col_count= 1; col_count <= num_char_cols; col_count++)
+ {
+ char rand_buffer[RAND_STRING_SIZE];
+ int buf_len= get_random_string(rand_buffer);
+
+ if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d = '%.*s'", col_count,
+ buf_len, rand_buffer)
+ > HUGE_STRING_LENGTH)
+ {
+ fprintf(stderr, "Memory Allocation error in creating update\n");
+ exit(1);
+ }
+ dynstr_append(&update_string, buf);
+
+ if (col_count < num_char_cols)
+ dynstr_append_mem(&update_string, ",", 1);
+ }
+
+ if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
+ dynstr_append(&update_string, " WHERE id = ");
+
+
+ ptr= (statement *)my_malloc(sizeof(statement),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+
+ ptr->string= (char *)my_malloc(update_string.length + 1,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ ptr->length= update_string.length+1;
+ if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
+ ptr->type= UPDATE_TYPE_REQUIRES_PREFIX ;
+ else
+ ptr->type= UPDATE_TYPE;
+ strmov(ptr->string, update_string.str);
+ dynstr_free(&update_string);
+ DBUG_RETURN(ptr);
+}
+
+
+/*
+ build_insert_string()
+
+ This function builds insert statements when the user opts to not supply
+ an insert file or string containing insert data
+*/
+static statement *
+build_insert_string(void)
+{
+ char buf[HUGE_STRING_LENGTH];
+ unsigned int col_count;
+ statement *ptr;
+ DYNAMIC_STRING insert_string;
+ DBUG_ENTER("build_insert_string");
+
+ init_dynamic_string(&insert_string, "", 1024, 1024);
+
+ dynstr_append(&insert_string, "INSERT INTO t1 VALUES (");
+
+ if (auto_generate_sql_autoincrement)
+ {
+ dynstr_append(&insert_string, "NULL");
+
+ if (num_int_cols || num_char_cols)
+ dynstr_append(&insert_string, ",");
+ }
+
+ if (auto_generate_sql_guid_primary)
+ {
+ dynstr_append(&insert_string, "uuid()");
+
+ if (num_int_cols || num_char_cols)
+ dynstr_append(&insert_string, ",");
+ }
+
+ if (auto_generate_sql_secondary_indexes)
+ {
+ unsigned int count;
+
+ for (count= 0; count < auto_generate_sql_secondary_indexes; count++)
+ {
+ if (count) /* Except for the first pass we add a comma */
+ dynstr_append(&insert_string, ",");
+
+ dynstr_append(&insert_string, "uuid()");
+ }
+
+ if (num_int_cols || num_char_cols)
+ dynstr_append(&insert_string, ",");
+ }
+
+ if (num_int_cols)
+ for (col_count= 1; col_count <= num_int_cols; col_count++)
+ {
+ if (snprintf(buf, HUGE_STRING_LENGTH, "%ld", random()) > HUGE_STRING_LENGTH)
+ {
+ fprintf(stderr, "Memory Allocation error in creating insert\n");
+ exit(1);
+ }
+ dynstr_append(&insert_string, buf);
+
+ if (col_count < num_int_cols || num_char_cols > 0)
+ dynstr_append_mem(&insert_string, ",", 1);
+ }
+
+ if (num_char_cols)
+ for (col_count= 1; col_count <= num_char_cols; col_count++)
+ {
+ int buf_len= get_random_string(buf);
+ dynstr_append_mem(&insert_string, "'", 1);
+ dynstr_append_mem(&insert_string, buf, buf_len);
+ dynstr_append_mem(&insert_string, "'", 1);
+
+ if (col_count < num_char_cols)
+ dynstr_append_mem(&insert_string, ",", 1);
+ }
+
+ dynstr_append_mem(&insert_string, ")", 1);
+
+ ptr= (statement *)my_malloc(sizeof(statement),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ ptr->string= (char *)my_malloc(insert_string.length + 1,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ ptr->length= insert_string.length+1;
+ ptr->type= INSERT_TYPE;
+ strmov(ptr->string, insert_string.str);
+ dynstr_free(&insert_string);
+ DBUG_RETURN(ptr);
+}
+
+
+/*
+ build_select_string()
+
+ This function builds a query if the user opts to not supply a query
+ statement or file containing a query statement
+*/
+static statement *
+build_select_string(my_bool key)
+{
+ char buf[HUGE_STRING_LENGTH];
+ unsigned int col_count;
+ statement *ptr;
+ static DYNAMIC_STRING query_string;
+ DBUG_ENTER("build_select_string");
+
+ init_dynamic_string(&query_string, "", 1024, 1024);
+
+ dynstr_append_mem(&query_string, "SELECT ", 7);
+ for (col_count= 1; col_count <= num_int_cols; col_count++)
+ {
+ if (snprintf(buf, HUGE_STRING_LENGTH, "intcol%d", col_count)
+ > HUGE_STRING_LENGTH)
+ {
+ fprintf(stderr, "Memory Allocation error in creating select\n");
+ exit(1);
+ }
+ dynstr_append(&query_string, buf);
+
+ if (col_count < num_int_cols || num_char_cols > 0)
+ dynstr_append_mem(&query_string, ",", 1);
+
+ }
+ for (col_count= 1; col_count <= num_char_cols; col_count++)
+ {
+ if (snprintf(buf, HUGE_STRING_LENGTH, "charcol%d", col_count)
+ > HUGE_STRING_LENGTH)
+ {
+ fprintf(stderr, "Memory Allocation error in creating select\n");
+ exit(1);
+ }
+ dynstr_append(&query_string, buf);
+
+ if (col_count < num_char_cols)
+ dynstr_append_mem(&query_string, ",", 1);
+
+ }
+ dynstr_append(&query_string, " FROM t1");
+
+ if ((key) &&
+ (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
+ dynstr_append(&query_string, " WHERE id = ");
+
+ ptr= (statement *)my_malloc(sizeof(statement),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ ptr->string= (char *)my_malloc(query_string.length + 1,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ ptr->length= query_string.length+1;
+ if ((key) &&
+ (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
+ ptr->type= SELECT_TYPE_REQUIRES_PREFIX;
+ else
+ ptr->type= SELECT_TYPE;
+ strmov(ptr->string, query_string.str);
+ dynstr_free(&query_string);
+ DBUG_RETURN(ptr);
+}
+
+static int
+get_options(int *argc,char ***argv)
+{
+ int ho_error;
+ char *tmp_string;
+ MY_STAT sbuf; /* Stat information for the data file */
+
+ DBUG_ENTER("get_options");
+ if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ if (!user)
+ user= (char *)"root";
+
+ if (create_string || auto_generate_sql)
+ {
+ if (verbose >= 1)
+ fprintf(stderr, "Turning off preserve-schema!\n");
+ opt_preserve= FALSE;
+ }
+
+ if (auto_generate_sql && (create_string || user_supplied_query))
+ {
+ fprintf(stderr,
+ "%s: Can't use --auto-generate-sql when create and query strings are specified!\n",
+ my_progname);
+ exit(1);
+ }
+
+ if (auto_generate_sql && auto_generate_sql_guid_primary &&
+ auto_generate_sql_autoincrement)
+ {
+ fprintf(stderr,
+ "%s: Either auto-generate-sql-guid-primary or auto-generate-sql-add-autoincrement can be used!\n",
+ my_progname);
+ exit(1);
+ }
+
+ /*
+ We are testing to make sure that if someone specified a key search
+ that we actually added a key!
+ */
+ if (auto_generate_sql && auto_generate_sql_type[0] == 'k')
+ if ( auto_generate_sql_autoincrement == FALSE &&
+ auto_generate_sql_guid_primary == FALSE)
+ {
+ fprintf(stderr,
+ "%s: Can't perform key test without a primary key!\n",
+ my_progname);
+ exit(1);
+ }
+
+
+
+ if (auto_generate_sql && num_of_query && auto_actual_queries)
+ {
+ fprintf(stderr,
+ "%s: Either auto-generate-sql-execute-number or number-of-queries can be used!\n",
+ my_progname);
+ exit(1);
+ }
+
+ parse_comma(concurrency_str ? concurrency_str : "1", &concurrency);
+
+ if (opt_csv_str)
+ {
+ opt_silent= TRUE;
+
+ if (opt_csv_str[0] == '-')
+ {
+ csv_file= fileno(stdout);
+ }
+ else
+ {
+ if ((csv_file= my_open(opt_csv_str, O_CREAT|O_WRONLY|O_APPEND, MYF(0)))
+ == -1)
+ {
+ fprintf(stderr,"%s: Could not open csv file: %sn\n",
+ my_progname, opt_csv_str);
+ exit(1);
+ }
+ }
+ }
+
+ if (opt_only_print)
+ opt_silent= TRUE;
+
+ if (num_int_cols_opt)
+ {
+ option_string *str;
+ parse_option(num_int_cols_opt, &str, ',');
+ num_int_cols= atoi(str->string);
+ if (str->option)
+ num_int_cols_index= atoi(str->option);
+ option_cleanup(str);
+ }
+
+ if (num_char_cols_opt)
+ {
+ option_string *str;
+ parse_option(num_char_cols_opt, &str, ',');
+ num_char_cols= atoi(str->string);
+ if (str->option)
+ num_char_cols_index= atoi(str->option);
+ else
+ num_char_cols_index= 0;
+ option_cleanup(str);
+ }
+
+
+ if (auto_generate_sql)
+ {
+ unsigned long long x= 0;
+ statement *ptr_statement;
+
+ if (verbose >= 2)
+ printf("Building Create Statements for Auto\n");
+
+ create_statements= build_table_string();
+ /*
+ Pre-populate table
+ */
+ for (ptr_statement= create_statements, x= 0;
+ x < auto_generate_sql_unique_write_number;
+ x++, ptr_statement= ptr_statement->next)
+ {
+ ptr_statement->next= build_insert_string();
+ }
+
+ if (verbose >= 2)
+ printf("Building Query Statements for Auto\n");
+
+ if (auto_generate_sql_type[0] == 'r')
+ {
+ if (verbose >= 2)
+ printf("Generating SELECT Statements for Auto\n");
+
+ query_statements= build_select_string(FALSE);
+ for (ptr_statement= query_statements, x= 0;
+ x < auto_generate_sql_unique_query_number;
+ x++, ptr_statement= ptr_statement->next)
+ {
+ ptr_statement->next= build_select_string(FALSE);
+ }
+ }
+ else if (auto_generate_sql_type[0] == 'k')
+ {
+ if (verbose >= 2)
+ printf("Generating SELECT for keys Statements for Auto\n");
+
+ query_statements= build_select_string(TRUE);
+ for (ptr_statement= query_statements, x= 0;
+ x < auto_generate_sql_unique_query_number;
+ x++, ptr_statement= ptr_statement->next)
+ {
+ ptr_statement->next= build_select_string(TRUE);
+ }
+ }
+ else if (auto_generate_sql_type[0] == 'w')
+ {
+ /*
+ We generate a number of strings in case the engine is
+ Archive (since strings which were identical one after another
+ would be too easily optimized).
+ */
+ if (verbose >= 2)
+ printf("Generating INSERT Statements for Auto\n");
+ query_statements= build_insert_string();
+ for (ptr_statement= query_statements, x= 0;
+ x < auto_generate_sql_unique_query_number;
+ x++, ptr_statement= ptr_statement->next)
+ {
+ ptr_statement->next= build_insert_string();
+ }
+ }
+ else if (auto_generate_sql_type[0] == 'u')
+ {
+ query_statements= build_update_string();
+ for (ptr_statement= query_statements, x= 0;
+ x < auto_generate_sql_unique_query_number;
+ x++, ptr_statement= ptr_statement->next)
+ {
+ ptr_statement->next= build_update_string();
+ }
+ }
+ else /* Mixed mode is default */
+ {
+ int coin= 0;
+
+ query_statements= build_insert_string();
+ /*
+ This logic should be extended to do a more mixed load,
+ at the moment it results in "every other".
+ */
+ for (ptr_statement= query_statements, x= 0;
+ x < auto_generate_sql_unique_query_number;
+ x++, ptr_statement= ptr_statement->next)
+ {
+ if (coin)
+ {
+ ptr_statement->next= build_insert_string();
+ coin= 0;
+ }
+ else
+ {
+ ptr_statement->next= build_select_string(TRUE);
+ coin= 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (create_string && my_stat(create_string, &sbuf, MYF(0)))
+ {
+ File data_file;
+ if (!MY_S_ISREG(sbuf.st_mode))
+ {
+ fprintf(stderr,"%s: Create file was not a regular file\n",
+ my_progname);
+ exit(1);
+ }
+ if ((data_file= my_open(create_string, O_RDWR, MYF(0))) == -1)
+ {
+ fprintf(stderr,"%s: Could not open create file\n", my_progname);
+ exit(1);
+ }
+ tmp_string= (char *)my_malloc(sbuf.st_size + 1,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ my_read(data_file, tmp_string, sbuf.st_size, MYF(0));
+ tmp_string[sbuf.st_size]= '\0';
+ my_close(data_file,MYF(0));
+ parse_delimiter(tmp_string, &create_statements, delimiter[0]);
+ my_free((gptr)tmp_string, MYF(0));
+ }
+ else if (create_string)
+ {
+ parse_delimiter(create_string, &create_statements, delimiter[0]);
+ }
+
+ if (user_supplied_query && my_stat(user_supplied_query, &sbuf, MYF(0)))
+ {
+ File data_file;
+ if (!MY_S_ISREG(sbuf.st_mode))
+ {
+ fprintf(stderr,"%s: User query supplied file was not a regular file\n",
+ my_progname);
+ exit(1);
+ }
+ if ((data_file= my_open(user_supplied_query, O_RDWR, MYF(0))) == -1)
+ {
+ fprintf(stderr,"%s: Could not open query supplied file\n", my_progname);
+ exit(1);
+ }
+ tmp_string= (char *)my_malloc(sbuf.st_size + 1,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ my_read(data_file, tmp_string, sbuf.st_size, MYF(0));
+ tmp_string[sbuf.st_size]= '\0';
+ my_close(data_file,MYF(0));
+ if (user_supplied_query)
+ actual_queries= parse_delimiter(tmp_string, &query_statements,
+ delimiter[0]);
+ my_free((gptr)tmp_string, MYF(0));
+ }
+ else if (user_supplied_query)
+ {
+ actual_queries= parse_delimiter(user_supplied_query, &query_statements,
+ delimiter[0]);
+ }
+ }
+
+ if (user_supplied_pre_statements && my_stat(user_supplied_pre_statements, &sbuf, MYF(0)))
+ {
+ File data_file;
+ if (!MY_S_ISREG(sbuf.st_mode))
+ {
+ fprintf(stderr,"%s: User query supplied file was not a regular file\n",
+ my_progname);
+ exit(1);
+ }
+ if ((data_file= my_open(user_supplied_pre_statements, O_RDWR, MYF(0))) == -1)
+ {
+ fprintf(stderr,"%s: Could not open query supplied file\n", my_progname);
+ exit(1);
+ }
+ tmp_string= (char *)my_malloc(sbuf.st_size + 1,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ my_read(data_file, tmp_string, sbuf.st_size, MYF(0));
+ tmp_string[sbuf.st_size]= '\0';
+ my_close(data_file,MYF(0));
+ if (user_supplied_pre_statements)
+ actual_queries= parse_delimiter(tmp_string, &pre_statements,
+ delimiter[0]);
+ my_free((gptr)tmp_string, MYF(0));
+ }
+ else if (user_supplied_pre_statements)
+ {
+ actual_queries= parse_delimiter(user_supplied_pre_statements, &pre_statements,
+ delimiter[0]);
+ }
+
+ if (user_supplied_post_statements && my_stat(user_supplied_post_statements, &sbuf, MYF(0)))
+ {
+ File data_file;
+ if (!MY_S_ISREG(sbuf.st_mode))
+ {
+ fprintf(stderr,"%s: User query supplied file was not a regular file\n",
+ my_progname);
+ exit(1);
+ }
+ if ((data_file= my_open(user_supplied_post_statements, O_RDWR, MYF(0))) == -1)
+ {
+ fprintf(stderr,"%s: Could not open query supplied file\n", my_progname);
+ exit(1);
+ }
+ tmp_string= (char *)my_malloc(sbuf.st_size + 1,
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ my_read(data_file, tmp_string, sbuf.st_size, MYF(0));
+ tmp_string[sbuf.st_size]= '\0';
+ my_close(data_file,MYF(0));
+ if (user_supplied_post_statements)
+ parse_delimiter(tmp_string, &post_statements,
+ delimiter[0]);
+ my_free((gptr)tmp_string, MYF(0));
+ }
+ else if (user_supplied_post_statements)
+ {
+ parse_delimiter(user_supplied_post_statements, &post_statements,
+ delimiter[0]);
+ }
+
+ if (verbose >= 2)
+ printf("Parsing engines to use.\n");
+
+ if (default_engine)
+ parse_option(default_engine, &engine_options, ',');
+
+ if (tty_password)
+ opt_password= get_tty_password(NullS);
+ DBUG_RETURN(0);
+}
+
+
+static int run_query(MYSQL *mysql, const char *query, int len)
+{
+ if (opt_only_print)
+ {
+ printf("%.*s;\n", len, query);
+ return 0;
+ }
+
+ if (verbose >= 3)
+ printf("%.*s;\n", len, query);
+ return mysql_real_query(mysql, query, len);
+}
+
+
+static int
+generate_primary_key_list(MYSQL *mysql, option_string *engine_stmt)
+{
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ unsigned long long counter;
+ DBUG_ENTER("generate_primary_key_list");
+
+ /*
+ Blackhole is a special case, this allows us to test the upper end
+ of the server during load runs.
+ */
+ if (opt_only_print || (engine_stmt &&
+ strstr(engine_stmt->string, "blackhole")))
+ {
+ primary_keys_number_of= 1;
+ primary_keys= (char **)my_malloc((uint)(sizeof(char *) *
+ primary_keys_number_of),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ /* Yes, we strdup a const string to simplify the interface */
+ primary_keys[0]= my_strdup("796c4422-1d94-102a-9d6d-00e0812d", MYF(0));
+ }
+ else
+ {
+ if (run_query(mysql, "SELECT id from t1", strlen("SELECT id from t1")))
+ {
+ fprintf(stderr,"%s: Cannot select GUID primary keys. (%s)\n", my_progname,
+ mysql_error(mysql));
+ exit(1);
+ }
+
+ result= mysql_store_result(mysql);
+ primary_keys_number_of= mysql_num_rows(result);
+
+ /* So why check this? Blackhole :) */
+ if (primary_keys_number_of)
+ {
+ /*
+ We create the structure and loop and create the items.
+ */
+ primary_keys= (char **)my_malloc((uint)(sizeof(char *) *
+ primary_keys_number_of),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ row= mysql_fetch_row(result);
+ for (counter= 0; counter < primary_keys_number_of;
+ counter++, row= mysql_fetch_row(result))
+ primary_keys[counter]= my_strdup(row[0], MYF(0));
+ }
+
+ mysql_free_result(result);
+ }
+
+ DBUG_RETURN(0);
+}
+
+static int
+drop_primary_key_list(void)
+{
+ unsigned long long counter;
+
+ if (primary_keys_number_of)
+ {
+ for (counter= 0; counter < primary_keys_number_of; counter++)
+ my_free((gptr)primary_keys[counter], MYF(0));
+
+ my_free((gptr)primary_keys, MYF(0));
+ }
+
+ return 0;
+}
+
+static int
+create_schema(MYSQL *mysql, const char *db, statement *stmt,
+ option_string *engine_stmt)
+{
+ char query[HUGE_STRING_LENGTH];
+ statement *ptr;
+ statement *after_create;
+ int len;
+ ulonglong count;
+ DBUG_ENTER("create_schema");
+
+ len= snprintf(query, HUGE_STRING_LENGTH, "CREATE SCHEMA `%s`", db);
+
+ if (verbose >= 2)
+ printf("Loading Pre-data\n");
+
+ if (run_query(mysql, query, len))
+ {
+ fprintf(stderr,"%s: Cannot create schema %s : %s\n", my_progname, db,
+ mysql_error(mysql));
+ exit(1);
+ }
+
+ if (opt_only_print)
+ {
+ printf("use %s;\n", db);
+ }
+ else
+ {
+ if (verbose >= 3)
+ printf("%s;\n", query);
+
+ if (mysql_select_db(mysql, db))
+ {
+ fprintf(stderr,"%s: Cannot select schema '%s': %s\n",my_progname, db,
+ mysql_error(mysql));
+ exit(1);
+ }
+ }
+
+ if (engine_stmt)
+ {
+ len= snprintf(query, HUGE_STRING_LENGTH, "set storage_engine=`%s`",
+ engine_stmt->string);
+ if (run_query(mysql, query, len))
+ {
+ fprintf(stderr,"%s: Cannot set default engine: %s\n", my_progname,
+ mysql_error(mysql));
+ exit(1);
+ }
+ }
+
+ count= 0;
+ after_create= stmt;
+
+limit_not_met:
+ for (ptr= after_create; ptr && ptr->length; ptr= ptr->next, count++)
+ {
+ if (auto_generate_sql && ( auto_generate_sql_number == count))
+ break;
+
+ if (engine_stmt && engine_stmt->option && ptr->type == CREATE_TABLE_TYPE)
+ {
+ char buffer[HUGE_STRING_LENGTH];
+
+ snprintf(buffer, HUGE_STRING_LENGTH, "%s %s", ptr->string,
+ engine_stmt->option);
+ if (run_query(mysql, buffer, strlen(buffer)))
+ {
+ fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
+ my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql));
+ exit(1);
+ }
+ }
+ else
+ {
+ if (run_query(mysql, ptr->string, ptr->length))
+ {
+ fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
+ my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql));
+ exit(1);
+ }
+ }
+ }
+
+ if (auto_generate_sql && (auto_generate_sql_number > count ))
+ {
+ /* Special case for auto create, we don't want to create tables twice */
+ after_create= stmt->next;
+ goto limit_not_met;
+ }
+
+ DBUG_RETURN(0);
+}
+
+static int
+drop_schema(MYSQL *mysql, const char *db)
+{
+ char query[HUGE_STRING_LENGTH];
+ int len;
+ DBUG_ENTER("drop_schema");
+ len= snprintf(query, HUGE_STRING_LENGTH, "DROP SCHEMA IF EXISTS `%s`", db);
+
+ if (run_query(mysql, query, len))
+ {
+ fprintf(stderr,"%s: Cannot drop database '%s' ERROR : %s\n",
+ my_progname, db, mysql_error(mysql));
+ exit(1);
+ }
+
+
+
+ DBUG_RETURN(0);
+}
+
+static int
+run_statements(MYSQL *mysql, statement *stmt)
+{
+ statement *ptr;
+ DBUG_ENTER("run_statements");
+
+ for (ptr= stmt; ptr && ptr->length; ptr= ptr->next)
+ {
+ if (run_query(mysql, ptr->string, ptr->length))
+ {
+ fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
+ my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql));
+ exit(1);
+ }
+ }
+
+ DBUG_RETURN(0);
+}
+
+static int
+run_scheduler(stats *sptr, statement *stmts, uint concur, ulonglong limit)
+{
+ uint x;
+ struct timeval start_time, end_time;
+ thread_context con;
+ pthread_t mainthread; /* Thread descriptor */
+ pthread_attr_t attr; /* Thread attributes */
+ DBUG_ENTER("run_scheduler");
+
+ con.stmt= stmts;
+ con.limit= limit;
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr,
+ PTHREAD_CREATE_DETACHED);
+
+ pthread_mutex_lock(&counter_mutex);
+ thread_counter= 0;
+
+ pthread_mutex_lock(&sleeper_mutex);
+ master_wakeup= 1;
+ pthread_mutex_unlock(&sleeper_mutex);
+ for (x= 0; x < concur; x++)
+ {
+ /* now you create the thread */
+ if (pthread_create(&mainthread, &attr, run_task,
+ (void *)&con) != 0)
+ {
+ fprintf(stderr,"%s: Could not create thread\n",
+ my_progname);
+ exit(0);
+ }
+ thread_counter++;
+ }
+ pthread_mutex_unlock(&counter_mutex);
+ pthread_attr_destroy(&attr);
+
+ pthread_mutex_lock(&sleeper_mutex);
+ master_wakeup= 0;
+ pthread_mutex_unlock(&sleeper_mutex);
+ pthread_cond_broadcast(&sleep_threshhold);
+
+ gettimeofday(&start_time, NULL);
+
+ /*
+ We loop until we know that all children have cleaned up.
+ */
+ pthread_mutex_lock(&counter_mutex);
+ while (thread_counter)
+ {
+ struct timespec abstime;
+
+ set_timespec(abstime, 3);
+ pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
+ }
+ pthread_mutex_unlock(&counter_mutex);
+
+ gettimeofday(&end_time, NULL);
+
+
+ sptr->timing= timedif(end_time, start_time);
+ sptr->users= concur;
+ sptr->rows= limit;
+
+ DBUG_RETURN(0);
+}
+
+
+pthread_handler_t run_task(void *p)
+{
+ ulonglong counter= 0, queries;
+ MYSQL *mysql;
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ statement *ptr;
+ thread_context *con= (thread_context *)p;
+
+ DBUG_ENTER("run_task");
+ DBUG_PRINT("info", ("task script \"%s\"", con->stmt ? con->stmt->string : ""));
+
+ pthread_mutex_lock(&sleeper_mutex);
+ while (master_wakeup)
+ {
+ pthread_cond_wait(&sleep_threshhold, &sleeper_mutex);
+ }
+ pthread_mutex_unlock(&sleeper_mutex);
+
+ if (!(mysql= mysql_init(NULL)))
+ {
+ fprintf(stderr,"%s: mysql_init() failed ERROR : %s\n",
+ my_progname, mysql_error(mysql));
+ exit(0);
+ }
+
+ if (mysql_thread_init())
+ {
+ fprintf(stderr,"%s: mysql_thread_init() failed ERROR : %s\n",
+ my_progname, mysql_error(mysql));
+ exit(0);
+ }
+
+ DBUG_PRINT("info", ("trying to connect to host %s as user %s", host, user));
+
+ if (!opt_only_print)
+ {
+ /* Connect to server */
+ static ulong connection_retry_sleep= 100000; /* Microseconds */
+ int i, connect_error= 1;
+ for (i= 0; i < 10; i++)
+ {
+ if (mysql_real_connect(mysql, host, user, opt_password,
+ create_schema_string,
+ opt_mysql_port,
+ opt_mysql_unix_port,
+ connect_flags))
+ {
+ /* Connect suceeded */
+ connect_error= 0;
+ break;
+ }
+ my_sleep(connection_retry_sleep);
+ }
+ if (connect_error)
+ {
+ fprintf(stderr,"%s: Error when connecting to server: %d %s\n",
+ my_progname, mysql_errno(mysql), mysql_error(mysql));
+ goto end;
+ }
+ }
+ DBUG_PRINT("info", ("connected."));
+ if (verbose >= 3)
+ printf("connected!\n");
+ queries= 0;
+
+limit_not_met:
+ for (ptr= con->stmt; ptr && ptr->length; ptr= ptr->next)
+ {
+ /*
+ We have to execute differently based on query type. This should become a function.
+ */
+ if ((ptr->type == UPDATE_TYPE_REQUIRES_PREFIX) ||
+ (ptr->type == SELECT_TYPE_REQUIRES_PREFIX))
+ {
+ int length;
+ unsigned int key_val;
+ char *key;
+ char buffer[HUGE_STRING_LENGTH];
+
+ /*
+ This should only happen if some sort of new engine was
+ implemented that didn't properly handle UPDATEs.
+
+ Just in case someone runs this under an experimental engine we don't
+ want a crash so the if() is placed here.
+ */
+ DBUG_ASSERT(primary_keys_number_of);
+ if (primary_keys_number_of)
+ {
+ key_val= (unsigned int)(random() % primary_keys_number_of);
+ key= primary_keys[key_val];
+
+ DBUG_ASSERT(key);
+
+ length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%s'",
+ (int)ptr->length, ptr->string, key);
+
+ if (run_query(mysql, buffer, length))
+ {
+ fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
+ my_progname, (uint)length, buffer, mysql_error(mysql));
+ exit(0);
+ }
+ }
+ }
+ else
+ {
+ if (run_query(mysql, ptr->string, ptr->length))
+ {
+ fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
+ my_progname, (uint)ptr->length, ptr->string, mysql_error(mysql));
+ exit(0);
+ }
+ }
+
+ if (mysql_field_count(mysql))
+ {
+ result= mysql_store_result(mysql);
+ while ((row = mysql_fetch_row(result)))
+ counter++;
+ mysql_free_result(result);
+ }
+ queries++;
+
+ if (con->limit && queries == con->limit)
+ goto end;
+ }
+
+ if (con->limit && queries < con->limit)
+ goto limit_not_met;
+
+end:
+
+ if (!opt_only_print)
+ mysql_close(mysql);
+
+ my_thread_end();
+
+ pthread_mutex_lock(&counter_mutex);
+ thread_counter--;
+ pthread_cond_signal(&count_threshhold);
+ pthread_mutex_unlock(&counter_mutex);
+
+ DBUG_RETURN(0);
+}
+
+uint
+parse_option(const char *origin, option_string **stmt, char delm)
+{
+ char *retstr;
+ char *ptr= (char *)origin;
+ option_string **sptr= stmt;
+ option_string *tmp;
+ uint length= strlen(origin);
+ uint count= 0; /* We know that there is always one */
+
+ for (tmp= *sptr= (option_string *)my_malloc(sizeof(option_string),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ (retstr= strchr(ptr, delm));
+ tmp->next= (option_string *)my_malloc(sizeof(option_string),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME)),
+ tmp= tmp->next)
+ {
+ char buffer[HUGE_STRING_LENGTH];
+ char *buffer_ptr;
+
+ count++;
+ strncpy(buffer, ptr, (size_t)(retstr - ptr));
+ if ((buffer_ptr= strchr(buffer, ':')))
+ {
+ char *option_ptr;
+
+ tmp->length= (size_t)(buffer_ptr - buffer);
+ tmp->string= my_strndup(ptr, (uint)tmp->length, MYF(MY_FAE));
+
+ option_ptr= ptr + 1 + tmp->length;
+
+ /* Move past the : and the first string */
+ tmp->option_length= (size_t)(retstr - option_ptr);
+ tmp->option= my_strndup(option_ptr, (uint)tmp->option_length,
+ MYF(MY_FAE));
+ }
+ else
+ {
+ tmp->string= my_strndup(ptr, (size_t)(retstr - ptr), MYF(MY_FAE));
+ tmp->length= (size_t)(retstr - ptr);
+ }
+
+ ptr+= retstr - ptr + 1;
+ if (isspace(*ptr))
+ ptr++;
+ count++;
+ }
+
+ if (ptr != origin+length)
+ {
+ char *origin_ptr;
+
+ if ((origin_ptr= strchr(ptr, ':')))
+ {
+ char *option_ptr;
+
+ tmp->length= (size_t)(origin_ptr - ptr);
+ tmp->string= my_strndup(origin, tmp->length, MYF(MY_FAE));
+
+ option_ptr= (char *)ptr + 1 + tmp->length;
+
+ /* Move past the : and the first string */
+ tmp->option_length= (size_t)((ptr + length) - option_ptr);
+ tmp->option= my_strndup(option_ptr, tmp->option_length,
+ MYF(MY_FAE));
+ }
+ else
+ {
+ tmp->length= (size_t)((ptr + length) - ptr);
+ tmp->string= my_strndup(ptr, tmp->length, MYF(MY_FAE));
+ }
+
+ count++;
+ }
+
+ return count;
+}
+
+
+uint
+parse_delimiter(const char *script, statement **stmt, char delm)
+{
+ char *retstr;
+ char *ptr= (char *)script;
+ statement **sptr= stmt;
+ statement *tmp;
+ uint length= strlen(script);
+ uint count= 0; /* We know that there is always one */
+
+ for (tmp= *sptr= (statement *)my_malloc(sizeof(statement),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+ (retstr= strchr(ptr, delm));
+ tmp->next= (statement *)my_malloc(sizeof(statement),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME)),
+ tmp= tmp->next)
+ {
+ count++;
+ tmp->string= my_strndup(ptr, (uint)(retstr - ptr), MYF(MY_FAE));
+ tmp->length= (size_t)(retstr - ptr);
+ ptr+= retstr - ptr + 1;
+ if (isspace(*ptr))
+ ptr++;
+ count++;
+ }
+
+ if (ptr != script+length)
+ {
+ tmp->string= my_strndup(ptr, (uint)((script + length) - ptr),
+ MYF(MY_FAE));
+ tmp->length= (size_t)((script + length) - ptr);
+ count++;
+ }
+
+ return count;
+}
+
+
+uint
+parse_comma(const char *string, uint **range)
+{
+ uint count= 1,x; /* We know that there is always one */
+ char *retstr;
+ char *ptr= (char *)string;
+ uint *nptr;
+
+ for (;*ptr; ptr++)
+ if (*ptr == ',') count++;
+
+ /* One extra spot for the NULL */
+ nptr= *range= (uint *)my_malloc(sizeof(uint) * (count + 1),
+ MYF(MY_ZEROFILL|MY_FAE|MY_WME));
+
+ ptr= (char *)string;
+ x= 0;
+ while ((retstr= strchr(ptr,',')))
+ {
+ nptr[x++]= atoi(ptr);
+ ptr+= retstr - ptr + 1;
+ }
+ nptr[x++]= atoi(ptr);
+
+ return count;
+}
+
+void
+print_conclusions(conclusions *con)
+{
+ printf("Benchmark\n");
+ if (con->engine)
+ printf("\tRunning for engine %s\n", con->engine);
+ printf("\tAverage number of seconds to run all queries: %ld.%03ld seconds\n",
+ con->avg_timing / 1000, con->avg_timing % 1000);
+ printf("\tMinimum number of seconds to run all queries: %ld.%03ld seconds\n",
+ con->min_timing / 1000, con->min_timing % 1000);
+ printf("\tMaximum number of seconds to run all queries: %ld.%03ld seconds\n",
+ con->max_timing / 1000, con->max_timing % 1000);
+ printf("\tNumber of clients running queries: %d\n", con->users);
+ printf("\tAverage number of queries per client: %llu\n", con->avg_rows);
+ printf("\n");
+}
+
+void
+print_conclusions_csv(conclusions *con)
+{
+ char buffer[HUGE_STRING_LENGTH];
+ const char *ptr= auto_generate_sql_type ? auto_generate_sql_type : "query";
+ snprintf(buffer, HUGE_STRING_LENGTH,
+ "%s,%s,%ld.%03ld,%ld.%03ld,%ld.%03ld,%d,%llu\n",
+ con->engine ? con->engine : "", /* Storage engine we ran against */
+ ptr, /* Load type */
+ con->avg_timing / 1000, con->avg_timing % 1000, /* Time to load */
+ con->min_timing / 1000, con->min_timing % 1000, /* Min time */
+ con->max_timing / 1000, con->max_timing % 1000, /* Max time */
+ con->users, /* Children used */
+ con->avg_rows /* Queries run */
+ );
+ my_write(csv_file, buffer, (uint)strlen(buffer), MYF(0));
+}
+
+void
+generate_stats(conclusions *con, option_string *eng, stats *sptr)
+{
+ stats *ptr;
+ unsigned int x;
+
+ con->min_timing= sptr->timing;
+ con->max_timing= sptr->timing;
+ con->min_rows= sptr->rows;
+ con->max_rows= sptr->rows;
+
+ /* At the moment we assume uniform */
+ con->users= sptr->users;
+ con->avg_rows= sptr->rows;
+
+ /* With no next, we know it is the last element that was malloced */
+ for (ptr= sptr, x= 0; x < iterations; ptr++, x++)
+ {
+ con->avg_timing+= ptr->timing;
+
+ if (ptr->timing > con->max_timing)
+ con->max_timing= ptr->timing;
+ if (ptr->timing < con->min_timing)
+ con->min_timing= ptr->timing;
+ }
+ con->avg_timing= con->avg_timing/iterations;
+
+ if (eng && eng->string)
+ con->engine= eng->string;
+ else
+ con->engine= NULL;
+}
+
+void
+option_cleanup(option_string *stmt)
+{
+ option_string *ptr, *nptr;
+ if (!stmt)
+ return;
+
+ for (ptr= stmt; ptr; ptr= nptr)
+ {
+ nptr= ptr->next;
+ if (ptr->string)
+ my_free((gptr)ptr->string, MYF(0));
+ if (ptr->option)
+ my_free((gptr)ptr->option, MYF(0));
+ my_free((gptr)(byte *)ptr, MYF(0));
+ }
+}
+
+void
+statement_cleanup(statement *stmt)
+{
+ statement *ptr, *nptr;
+ if (!stmt)
+ return;
+
+ for (ptr= stmt; ptr; ptr= nptr)
+ {
+ nptr= ptr->next;
+ if (ptr->string)
+ my_free((gptr)ptr->string, MYF(0));
+ my_free((gptr)(byte *)ptr, MYF(0));
+ }
+}
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 5640d0c24ba..1ba20c8929f 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -33,18 +33,12 @@
#define MTEST_VERSION "3.2"
-#include <my_global.h>
-#include <mysql_embed.h>
-#include <my_sys.h>
-#include <m_string.h>
-#include <mysql.h>
+#include "client_priv.h"
#include <mysql_version.h>
#include <mysqld_error.h>
-#include <errmsg.h>
#include <m_ctype.h>
#include <my_dir.h>
#include <hash.h>
-#include <my_getopt.h>
#include <stdarg.h>
#include <violite.h>
#include "my_regex.h" /* Our own version of regex */
@@ -52,14 +46,6 @@
#include <sys/wait.h>
#endif
-#ifndef WEXITSTATUS
-# ifdef __WIN__
-# define WEXITSTATUS(stat_val) (stat_val)
-# else
-# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
-# endif
-#endif
-
/* Use cygwin for --exec and --system before 5.0 */
#if MYSQL_VERSION_ID < 50000
#define USE_CYGWIN
@@ -81,11 +67,9 @@
};
enum {
- OPT_SKIP_SAFEMALLOC=256, OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT,
- OPT_SSL_CA, OPT_SSL_CAPATH, OPT_SSL_CIPHER, OPT_PS_PROTOCOL,
- OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
- OPT_SSL_VERIFY_SERVER_CERT, OPT_MAX_CONNECT_RETRIES,
- OPT_MARK_PROGRESS, OPT_CHARSETS_DIR, OPT_LOG_DIR
+ OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION,
+ OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
+ OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR
};
static int record= 0, opt_sleep= -1;
@@ -1562,7 +1546,7 @@ void do_source(struct st_command *command)
{
static DYNAMIC_STRING ds_filename;
const struct command_arg source_args[] = {
- "filename", ARG_STRING, TRUE, &ds_filename, "File to source"
+ { "filename", ARG_STRING, TRUE, &ds_filename, "File to source" }
};
DBUG_ENTER("do_source");
@@ -1948,7 +1932,7 @@ void do_remove_file(struct st_command *command)
int error;
static DYNAMIC_STRING ds_filename;
const struct command_arg rm_args[] = {
- "filename", ARG_STRING, TRUE, &ds_filename, "File to delete"
+ { "filename", ARG_STRING, TRUE, &ds_filename, "File to delete" }
};
DBUG_ENTER("do_remove_file");
@@ -1982,8 +1966,8 @@ void do_copy_file(struct st_command *command)
static DYNAMIC_STRING ds_from_file;
static DYNAMIC_STRING ds_to_file;
const struct command_arg copy_file_args[] = {
- "from_file", ARG_STRING, TRUE, &ds_from_file, "Filename to copy from",
- "to_file", ARG_STRING, TRUE, &ds_to_file, "Filename to copy to"
+ { "from_file", ARG_STRING, TRUE, &ds_from_file, "Filename to copy from" },
+ { "to_file", ARG_STRING, TRUE, &ds_to_file, "Filename to copy to" }
};
DBUG_ENTER("do_copy_file");
@@ -2019,8 +2003,8 @@ void do_chmod_file(struct st_command *command)
static DYNAMIC_STRING ds_mode;
static DYNAMIC_STRING ds_file;
const struct command_arg chmod_file_args[] = {
- "mode", ARG_STRING, TRUE, &ds_mode, "Mode of file",
- "file", ARG_STRING, TRUE, &ds_file, "Filename of file to modify"
+ { "mode", ARG_STRING, TRUE, &ds_mode, "Mode of file" },
+ { "file", ARG_STRING, TRUE, &ds_file, "Filename of file to modify" }
};
DBUG_ENTER("do_chmod_file");
@@ -2057,7 +2041,7 @@ void do_file_exist(struct st_command *command)
int error;
static DYNAMIC_STRING ds_filename;
const struct command_arg file_exist_args[] = {
- "filename", ARG_STRING, TRUE, &ds_filename, "File to check if it exist"
+ { "filename", ARG_STRING, TRUE, &ds_filename, "File to check if it exist" }
};
DBUG_ENTER("do_file_exist");
@@ -2139,8 +2123,8 @@ void do_write_file_command(struct st_command *command, my_bool append)
static DYNAMIC_STRING ds_filename;
static DYNAMIC_STRING ds_delimiter;
const struct command_arg write_file_args[] = {
- "filename", ARG_STRING, TRUE, &ds_filename, "File to write to",
- "delimiter", ARG_STRING, FALSE, &ds_delimiter, "Delimiter to read until"
+ { "filename", ARG_STRING, TRUE, &ds_filename, "File to write to" },
+ { "delimiter", ARG_STRING, FALSE, &ds_delimiter, "Delimiter to read until" }
};
DBUG_ENTER("do_write_file");
@@ -2248,7 +2232,7 @@ void do_cat_file(struct st_command *command)
char buff[512];
static DYNAMIC_STRING ds_filename;
const struct command_arg cat_file_args[] = {
- "filename", ARG_STRING, TRUE, &ds_filename, "File to read from"
+ { "filename", ARG_STRING, TRUE, &ds_filename, "File to read from" }
};
DBUG_ENTER("do_cat_file");
@@ -2312,8 +2296,8 @@ void do_diff_files(struct st_command *command)
static DYNAMIC_STRING ds_filename;
static DYNAMIC_STRING ds_filename2;
const struct command_arg diff_file_args[] = {
- "file1", ARG_STRING, TRUE, &ds_filename, "First file to diff",
- "file2", ARG_STRING, TRUE, &ds_filename2, "Second file to diff"
+ { "file1", ARG_STRING, TRUE, &ds_filename, "First file to diff" },
+ { "file2", ARG_STRING, TRUE, &ds_filename2, "Second file to diff" }
};
DBUG_ENTER("do_diff_files");
@@ -2389,7 +2373,7 @@ void do_perl(struct st_command *command)
static DYNAMIC_STRING ds_script;
static DYNAMIC_STRING ds_delimiter;
const struct command_arg perl_args[] = {
- "delimiter", ARG_STRING, FALSE, &ds_delimiter, "Delimiter to read until"
+ { "delimiter", ARG_STRING, FALSE, &ds_delimiter, "Delimiter to read until" }
};
DBUG_ENTER("do_perl");
@@ -2535,17 +2519,20 @@ wait_for_position:
if (!(res= mysql_store_result(mysql)))
die("mysql_store_result() returned NULL for '%s'", query_buf);
if (!(row= mysql_fetch_row(res)))
+ {
+ mysql_free_result(res);
die("empty result in %s", query_buf);
+ }
if (!row[0])
{
/*
It may be that the slave SQL thread has not started yet, though START
SLAVE has been issued ?
*/
+ mysql_free_result(res);
if (tries++ == 30)
die("could not sync with master ('%s' returned NULL)", query_buf);
sleep(1); /* So at most we will wait 30 seconds and make 31 tries */
- mysql_free_result(res);
goto wait_for_position;
}
mysql_free_result(res);
@@ -2586,6 +2573,7 @@ int do_save_master_pos()
MYSQL *mysql = &cur_con->mysql;
const char *query;
int rpl_parse;
+ DBUG_ENTER("do_save_master_pos");
rpl_parse = mysql_rpl_parse_enabled(mysql);
mysql_disable_rpl_parse(mysql);
@@ -2610,7 +2598,7 @@ int do_save_master_pos()
if (have_ndbcluster)
{
- ulonglong start_epoch= 0, applied_epoch= 0,
+ ulonglong start_epoch= 0, handled_epoch= 0,
latest_epoch=0, latest_trans_epoch=0,
latest_handled_binlog_epoch= 0, latest_received_binlog_epoch= 0,
latest_applied_binlog_epoch= 0;
@@ -2713,9 +2701,9 @@ int do_save_master_pos()
if (!row)
die("result does not contain '%s' in '%s'",
binlog, query);
- if (latest_applied_binlog_epoch > applied_epoch)
+ if (latest_handled_binlog_epoch > handled_epoch)
count= 0;
- applied_epoch= latest_applied_binlog_epoch;
+ handled_epoch= latest_handled_binlog_epoch;
count++;
if (latest_handled_binlog_epoch >= start_epoch)
do_continue= 0;
@@ -2743,7 +2731,7 @@ int do_save_master_pos()
if (rpl_parse)
mysql_enable_rpl_parse(mysql);
- return 0;
+ DBUG_RETURN(0);
}
@@ -3198,7 +3186,7 @@ struct st_connection * find_connection_by_name(const char *name)
int select_connection_name(const char *name)
{
- DBUG_ENTER("select_connection2");
+ DBUG_ENTER("select_connection_name");
DBUG_PRINT("enter",("name: '%s'", name));
if (!(cur_con= find_connection_by_name(name)))
@@ -3221,7 +3209,7 @@ int select_connection(struct st_command *command)
if (*p)
*p++= 0;
command->last_argument= p;
- return select_connection_name(name);
+ DBUG_RETURN(select_connection_name(name));
}
@@ -3464,18 +3452,14 @@ void do_connect(struct st_command *command)
static DYNAMIC_STRING ds_sock;
static DYNAMIC_STRING ds_options;
const struct command_arg connect_args[] = {
- "connection name", ARG_STRING, TRUE, &ds_connection_name,
- "Name of the connection",
- "host", ARG_STRING, TRUE, &ds_host, "Host to connect to",
- "user", ARG_STRING, FALSE, &ds_user, "User to connect as",
- "passsword", ARG_STRING, FALSE, &ds_password,
- "Password used when connecting",
- "database", ARG_STRING, FALSE, &ds_database,
- "Dtabase to select after connect",
- "port", ARG_STRING, FALSE, &ds_port, "Port to connect to",
- "socket", ARG_STRING, FALSE, &ds_sock, "Socket to connect with",
- "options", ARG_STRING, FALSE, &ds_options,
- "Options to use while connecting"
+ { "connection name", ARG_STRING, TRUE, &ds_connection_name, "Name of the connection" },
+ { "host", ARG_STRING, TRUE, &ds_host, "Host to connect to" },
+ { "user", ARG_STRING, FALSE, &ds_user, "User to connect as" },
+ { "passsword", ARG_STRING, FALSE, &ds_password, "Password used when connecting" },
+ { "database", ARG_STRING, FALSE, &ds_database, "Database to select after connect" },
+ { "port", ARG_STRING, FALSE, &ds_port, "Port to connect to" },
+ { "socket", ARG_STRING, FALSE, &ds_sock, "Socket to connect with" },
+ { "options", ARG_STRING, FALSE, &ds_options, "Options to use while connecting" }
};
DBUG_ENTER("do_connect");
diff --git a/client/sql_string.h b/client/sql_string.h
index a74fbf58082..da19c1ccfe5 100644
--- a/client/sql_string.h
+++ b/client/sql_string.h
@@ -23,8 +23,6 @@
#define NOT_FIXED_DEC 31
#endif
-#define STRING_WITH_LEN(X) ((const char*) X), ((uint) (sizeof(X) - 1))
-
class String;
int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);