summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/.cvsignore14
-rw-r--r--[-rwxr-xr-x]client/CMakeLists.txt113
-rw-r--r--client/Makefile.am127
-rw-r--r--client/client_priv.h51
-rw-r--r--client/completion_hash.cc7
-rw-r--r--client/my_readline.h5
-rw-r--r--client/mysql.cc352
-rw-r--r--client/mysql_plugin.c1205
-rw-r--r--client/mysql_upgrade.c50
-rw-r--r--client/mysqladmin.cc123
-rw-r--r--client/mysqlbinlog.cc108
-rw-r--r--client/mysqlcheck.c136
-rw-r--r--client/mysqldump.c635
-rw-r--r--client/mysqlimport.c56
-rw-r--r--client/mysqlshow.c40
-rw-r--r--client/mysqlslap.c100
-rw-r--r--client/mysqltest.cc1175
-rw-r--r--client/readline.cc12
-rw-r--r--client/sql_string.cc100
-rw-r--r--client/sql_string.h17
20 files changed, 3117 insertions, 1309 deletions
diff --git a/client/.cvsignore b/client/.cvsignore
deleted file mode 100644
index 54bbaed97f5..00000000000
--- a/client/.cvsignore
+++ /dev/null
@@ -1,14 +0,0 @@
-.deps
-.libs
-Makefile
-Makefile.in
-insert_test
-mysql
-mysql-test
-mysql_test
-mysqladmin
-mysqldump
-mysqlimport
-mysqlshow
-select_test
-thread_test
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index b4b633d007c..4d8fab3f4b9 100755..100644
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -1,5 +1,4 @@
-# Copyright (c) 2006-2008 MySQL AB, 2009 Sun Microsystems, Inc.
-# Use is subject to license terms.
+# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -12,75 +11,69 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake")
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+INCLUDE_DIRECTORIES(
+ ${CMAKE_SOURCE_DIR}/include
+ ${ZLIB_INCLUDE_DIR}
+ ${SSL_INCLUDE_DIRS}
+ ${CMAKE_SOURCE_DIR}/libmysql
+ ${CMAKE_SOURCE_DIR}/regex
+ ${CMAKE_SOURCE_DIR}/sql
+ ${CMAKE_SOURCE_DIR}/strings
+ ${READLINE_INCLUDE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+ADD_DEFINITIONS(${READLINE_DEFINES})
+ADD_DEFINITIONS(${SSL_DEFINES})
+MYSQL_ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc)
+TARGET_LINK_LIBRARIES(mysql mysqlclient)
+IF(UNIX)
+ TARGET_LINK_LIBRARIES(mysql ${READLINE_LIBRARY})
+ENDIF(UNIX)
+
+MYSQL_ADD_EXECUTABLE(mysqltest mysqltest.cc COMPONENT Test)
+SET_SOURCE_FILES_PROPERTIES(mysqltest.cc PROPERTIES COMPILE_FLAGS "-DTHREADS")
+TARGET_LINK_LIBRARIES(mysqltest mysqlclient regex)
-# We use the "mysqlclient_notls" library here just as safety, in case
-# any of the clients here would go beyond the client API and access the
-# Thread Local Storage directly.
-SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+MYSQL_ADD_EXECUTABLE(mysqlcheck mysqlcheck.c)
+TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient)
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
- ${CMAKE_SOURCE_DIR}/zlib
- ${CMAKE_SOURCE_DIR}/extra/yassl/include
- ${CMAKE_SOURCE_DIR}/libmysql
- ${CMAKE_SOURCE_DIR}/regex
- ${CMAKE_SOURCE_DIR}/sql
- ${CMAKE_SOURCE_DIR}/strings)
+MYSQL_ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c)
+TARGET_LINK_LIBRARIES(mysqldump mysqlclient)
-ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c)
-TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32)
+MYSQL_ADD_EXECUTABLE(mysqlimport mysqlimport.c)
+TARGET_LINK_LIBRARIES(mysqlimport mysqlclient)
-ADD_EXECUTABLE(mysqltest mysqltest.cc)
-SET_SOURCE_FILES_PROPERTIES(mysqltest.cc PROPERTIES COMPILE_FLAGS "-DTHREADS")
-TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys regex wsock32 dbug)
+MYSQL_ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c)
+TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient)
+ADD_DEPENDENCIES(mysql_upgrade GenFixPrivs)
-ADD_EXECUTABLE(mysqlcheck mysqlcheck.c)
-TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient_notls wsock32)
+MYSQL_ADD_EXECUTABLE(mysqlshow mysqlshow.c)
+TARGET_LINK_LIBRARIES(mysqlshow mysqlclient)
-ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c ../mysys/mf_getdate.c)
-TARGET_LINK_LIBRARIES(mysqldump mysqlclient_notls wsock32)
+MYSQL_ADD_EXECUTABLE(mysql_plugin mysql_plugin.c)
+TARGET_LINK_LIBRARIES(mysql_plugin mysqlclient)
-ADD_EXECUTABLE(mysqlimport mysqlimport.c)
-TARGET_LINK_LIBRARIES(mysqlimport mysqlclient_notls wsock32)
+MYSQL_ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc)
+TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient)
-ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c ../mysys/my_getpagesize.c)
-TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient_notls wsock32)
-ADD_DEPENDENCIES(mysql_upgrade GenFixPrivs)
+MYSQL_ADD_EXECUTABLE(mysqladmin mysqladmin.cc)
+TARGET_LINK_LIBRARIES(mysqladmin mysqlclient)
-ADD_EXECUTABLE(mysqlshow mysqlshow.c)
-TARGET_LINK_LIBRARIES(mysqlshow mysqlclient_notls wsock32)
+MYSQL_ADD_EXECUTABLE(mysqlslap mysqlslap.c)
+SET_SOURCE_FILES_PROPERTIES(mysqlslap.c PROPERTIES COMPILE_FLAGS "-DTHREADS")
+TARGET_LINK_LIBRARIES(mysqlslap mysqlclient)
-ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc
- ../mysys/mf_tempdir.c
- ../mysys/my_new.cc
- ../mysys/my_bit.c
- ../mysys/my_bitmap.c
- ../mysys/my_vle.c
- ../mysys/base64.c)
-TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient_notls wsock32)
+# "WIN32" also covers 64 bit. "echo" is used in some files below "mysql-test/".
+IF(WIN32)
+ MYSQL_ADD_EXECUTABLE(echo echo.c)
+ENDIF(WIN32)
-ADD_EXECUTABLE(mysqladmin mysqladmin.cc)
-TARGET_LINK_LIBRARIES(mysqladmin mysqlclient_notls wsock32)
+SET_TARGET_PROPERTIES (mysqlcheck mysqldump mysqlimport mysql_upgrade mysqlshow mysqlslap mysql_plugin
+PROPERTIES HAS_CXX TRUE)
-ADD_EXECUTABLE(mysqlslap mysqlslap.c)
-SET_SOURCE_FILES_PROPERTIES(mysqlslap.c PROPERTIES COMPILE_FLAGS "-DTHREADS")
-TARGET_LINK_LIBRARIES(mysqlslap mysqlclient mysys zlib wsock32 dbug)
-
-ADD_EXECUTABLE(echo echo.c)
-
-IF(EMBED_MANIFESTS)
- MYSQL_EMBED_MANIFEST("mysql" "asInvoker")
- MYSQL_EMBED_MANIFEST("mysqltest" "asInvoker")
- MYSQL_EMBED_MANIFEST("mysqlcheck" "asInvoker")
- MYSQL_EMBED_MANIFEST("mysqldump" "asInvoker")
- MYSQL_EMBED_MANIFEST("mysqlimport" "asInvoker")
- MYSQL_EMBED_MANIFEST("mysql_upgrade" "asInvoker")
- MYSQL_EMBED_MANIFEST("mysqlshow" "asInvoker")
- MYSQL_EMBED_MANIFEST("mysqlbinlog" "asInvoker")
- MYSQL_EMBED_MANIFEST("mysqladmin" "asInvoker")
- MYSQL_EMBED_MANIFEST("echo" "asInvoker")
-ENDIF(EMBED_MANIFESTS)
+ADD_DEFINITIONS(-DHAVE_DLOPEN)
diff --git a/client/Makefile.am b/client/Makefile.am
deleted file mode 100644
index 1e7a9359462..00000000000
--- a/client/Makefile.am
+++ /dev/null
@@ -1,127 +0,0 @@
-# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-# This file is public domain and comes with NO WARRANTY of any kind
-
-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@ $(CLIENT_THREAD_LIBS) \
- $(top_builddir)/libmysql/libmysqlclient.la
-
-noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \
- client_priv.h
-
-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
-
-mysqlbinlog_SOURCES = mysqlbinlog.cc \
- $(top_srcdir)/mysys/mf_tempdir.c \
- $(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)
-
-mysqldump_SOURCES= mysqldump.c \
- my_user.c \
- $(top_srcdir)/mysys/mf_getdate.c
-
-mysqlimport_SOURCES= mysqlimport.c
-mysqlimport_CFLAGS= -DTHREAD -UUNDEF_THREADS_HACK
-mysqlimport_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
- @CLIENT_EXTRA_LDFLAGS@ \
- $(LIBMYSQLCLIENT_LA) \
- $(top_builddir)/mysys/libmysys.a
-
-mysqlshow_SOURCES= mysqlshow.c
-
-mysqlslap_SOURCES= mysqlslap.c
-mysqlslap_CFLAGS= -DTHREAD -UMYSQL_CLIENT_NO_THREADS
-mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
- @CLIENT_EXTRA_LDFLAGS@ \
- $(LIBMYSQLCLIENT_LA) \
- $(top_builddir)/mysys/libmysys.a
-
-mysqltest_SOURCES= mysqltest.cc
-mysqltest_CXXFLAGS= -DTHREAD -UMYSQL_CLIENT_NO_THREADS
-mysqltest_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
- @CLIENT_EXTRA_LDFLAGS@ \
- $(LIBMYSQLCLIENT_LA) \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/regex/libregex.a \
- $(CLIENT_THREAD_LIBS)
-
-mysql_upgrade_SOURCES= mysql_upgrade.c \
- $(top_srcdir)/mysys/my_getpagesize.c
-
-# Fix for mit-threads
-DEFS = -DMYSQL_CLIENT_NO_THREADS \
- -DDEFAULT_MYSQL_HOME="\"$(prefix)\"" \
- -DMYSQL_DATADIR="\"$(localstatedir)\""
-
-sql_src=log_event.h mysql_priv.h rpl_constants.h \
- rpl_utility.h rpl_tblmap.h rpl_tblmap.cc \
- log_event.cc my_decimal.h my_decimal.cc \
- log_event_old.h log_event_old.cc \
- rpl_record_old.h rpl_record_old.cc
-strings_src=decimal.c
-
-link_sources:
- for f in $(sql_src) ; do \
- rm -f $$f; \
- @LN_CP_F@ $(top_srcdir)/sql/$$f $$f; \
- done; \
- for f in $(strings_src) ; do \
- rm -f $$f; \
- @LN_CP_F@ $(top_srcdir)/strings/$$f $$f; \
- done; \
- rm -f 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 ca3a7bc6d90..2362811d2b3 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -21,7 +21,6 @@
#include <my_sys.h>
#include <m_string.h>
#include <mysql.h>
-#include <mysql_embed.h>
#include <errmsg.h>
#include <my_getopt.h>
@@ -33,19 +32,10 @@
# endif
#endif
-/* Version numbers for deprecation messages */
-#define VER_CELOSIA "5.6"
-
-#define WARN_DEPRECATED(Ver,Old,New) \
- do { \
- printf("Warning: The option '%s' is deprecated and will be removed " \
- "in a future release. Please use %s instead.\n", (Old), (New)); \
- } while(0);
-
enum options_client
{
OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET,
- OPT_PAGER, OPT_NOPAGER, OPT_TEE, OPT_NOTEE,
+ OPT_PAGER, OPT_TEE,
OPT_LOW_PRIORITY, OPT_AUTO_REPAIR, OPT_COMPRESS,
OPT_DROP, OPT_LOCKS, OPT_KEYWORDS, OPT_DELAYED, OPT_OPTIMIZE,
OPT_FTB, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_TABLES,
@@ -60,11 +50,8 @@ enum options_client
OPT_SHARED_MEMORY_BASE_NAME, OPT_FRM, OPT_SKIP_OPTIMIZATION,
OPT_COMPATIBLE, OPT_RECONNECT, OPT_DELIMITER, OPT_SECURE_AUTH,
OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_SERVER_ARG,
- OPT_POSITION, OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME,
+ OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME,
OPT_SIGINT_IGNORE, OPT_HEXBLOB, OPT_ORDER_BY_PRIMARY, OPT_COUNT,
-#ifdef HAVE_NDBCLUSTER_DB
- OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING,
-#endif
OPT_TRIGGERS,
OPT_MYSQL_ONLY_PRINT,
OPT_MYSQL_LOCK_DIRECTORY,
@@ -72,7 +59,10 @@ enum options_client
OPT_IMPORT_USE_THREADS,
OPT_MYSQL_NUMBER_OF_QUERY,
OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
- OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_CREATE_SLAP_SCHEMA,
+ OPT_TZ_UTC, OPT_CREATE_SLAP_SCHEMA,
+ OPT_MYSQLDUMP_SLAVE_APPLY,
+ OPT_MYSQLDUMP_SLAVE_DATA,
+ OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT,
OPT_SLAP_CSV, OPT_SLAP_CREATE_STRING,
OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE, OPT_SLAP_AUTO_GENERATE_WRITE_NUM,
OPT_SLAP_AUTO_GENERATE_ADD_AUTO,
@@ -90,9 +80,34 @@ enum options_client
OPT_SLAP_NO_DROP,
OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT_MODE, OPT_SERVER_ID,
OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT,
+ OPT_AUTO_VERTICAL_OUTPUT,
OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE,
OPT_WRITE_BINLOG, OPT_DUMP_DATE,
- OPT_FIRST_SLAVE,
- OPT_ALL,
+ OPT_INIT_COMMAND,
+ OPT_PLUGIN_DIR,
+ OPT_DEFAULT_AUTH,
+ OPT_DEFAULT_PLUGIN,
+ OPT_ENABLE_CLEARTEXT_PLUGIN,
OPT_MAX_CLIENT_OPTION
};
+
+/**
+ First mysql version supporting the information schema.
+*/
+#define FIRST_INFORMATION_SCHEMA_VERSION 50003
+
+/**
+ Name of the information schema database.
+*/
+#define INFORMATION_SCHEMA_DB_NAME "information_schema"
+
+/**
+ First mysql version supporting the performance schema.
+*/
+#define FIRST_PERFORMANCE_SCHEMA_VERSION 50503
+
+/**
+ Name of the performance schema database.
+*/
+#define PERFORMANCE_SCHEMA_DB_NAME "performance_schema"
+
diff --git a/client/completion_hash.cc b/client/completion_hash.cc
index cd0ea17dfaf..9ffb2082c06 100644
--- a/client/completion_hash.cc
+++ b/client/completion_hash.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
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
@@ -11,7 +11,7 @@
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 */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* Quick & light hash implementation for tab completion purposes
*
@@ -22,7 +22,6 @@
#include <my_global.h>
#include <m_string.h>
-#undef SAFEMALLOC // Speed things up
#include <my_sys.h>
#include "completion_hash.h"
@@ -213,7 +212,7 @@ void completion_hash_clean(HashTable *ht)
void completion_hash_free(HashTable *ht)
{
completion_hash_clean(ht);
- my_free(ht->arBuckets, MYF(0));
+ my_free(ht->arBuckets);
}
diff --git a/client/my_readline.h b/client/my_readline.h
index b556fa0cf83..d288a33e1cc 100644
--- a/client/my_readline.h
+++ b/client/my_readline.h
@@ -1,3 +1,6 @@
+#ifndef CLIENT_MY_READLINE_INCLUDED
+#define CLIENT_MY_READLINE_INCLUDED
+
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
@@ -35,3 +38,5 @@ extern LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file);
extern LINE_BUFFER *batch_readline_command(LINE_BUFFER *buffer, char * str);
extern char *batch_readline(LINE_BUFFER *buffer);
extern void batch_readline_end(LINE_BUFFER *buffer);
+
+#endif /* CLIENT_MY_READLINE_INCLUDED */
diff --git a/client/mysql.cc b/client/mysql.cc
index 965b1929af8..b772fe67cc4 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -56,11 +56,6 @@ static char *server_version= NULL;
/* Array of options to pass to libemysqld */
#define MAX_SERVER_ARGS 64
-/* Version numbers for deprecation messages */
-#define VER_CELOSIA "5.6"
-
-void* sql_alloc(unsigned size); // Don't use mysqld alloc for these
-void sql_element_free(void *ptr);
#include "sql_string.h"
extern "C" {
@@ -92,9 +87,10 @@ extern "C" {
#if defined(__WIN__)
#include <conio.h>
-#elif !defined(__NETWARE__)
+#else
#include <readline/readline.h>
#define HAVE_READLINE
+#define USE_POPEN
#endif
//int vidattr(long unsigned int attrs); // Was missing in sun curses
}
@@ -104,16 +100,12 @@ extern "C" {
#define vidattr(A) {} // Can't get this to work
#endif
-#ifdef FN_NO_CASE_SENCE
+#ifdef FN_NO_CASE_SENSE
#define cmp_database(cs,A,B) my_strcasecmp((cs), (A), (B))
#else
#define cmp_database(cs,A,B) strcmp((A),(B))
#endif
-#if !defined(__WIN__) && !defined(__NETWARE__) && !defined(THREAD)
-#define USE_POPEN
-#endif
-
#include "completion_hash.h"
#include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE
@@ -146,8 +138,9 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0,
vertical=0, line_numbers=1, column_names=1,opt_html=0,
opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0,
tty_password= 0, opt_nobeep=0, opt_reconnect=1,
- default_charset_used= 0, opt_secure_auth= 0,
+ opt_secure_auth= 0,
default_pager_set= 0, opt_sigint_ignore= 0,
+ auto_vertical_output= 0,
show_warnings= 0, executing_query= 0, interrupted_query= 0,
ignore_spaces= 0;
static my_bool debug_info_flag, debug_check_flag;
@@ -155,12 +148,15 @@ static my_bool column_types_flag;
static my_bool preserve_comments= 0;
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 uint opt_enable_cleartext_plugin= 0;
+static my_bool using_opt_enable_cleartext_plugin= 0;
static uint my_end_arg;
static char * opt_mysql_unix_port=0;
static int connect_flag=CLIENT_INTERACTIVE;
static char *current_host,*current_db,*current_user=0,*opt_password=0,
*current_prompt=0, *delimiter_str= 0,
- *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
+ *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME,
+ *opt_init_command= 0;
static char *histfile;
static char *histfile_tmp;
static String glob_buffer,old_buffer;
@@ -170,6 +166,7 @@ static int wait_time = 5;
static STATUS status;
static ulong select_limit,max_join_size,opt_connect_timeout=0;
static char mysql_charsets_dir[FN_REFLEN+1];
+static char *opt_plugin_dir= 0, *opt_default_auth= 0;
static const char *xmlmeta[] = {
"&", "&amp;",
"<", "&lt;",
@@ -189,6 +186,7 @@ static MEM_ROOT hash_mem_root;
static uint prompt_counter;
static char delimiter[16]= DEFAULT_DELIMITER;
static uint delimiter_length= 1;
+unsigned short terminal_width= 80;
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
@@ -242,6 +240,8 @@ static const char* construct_prompt();
static char *get_arg(char *line, my_bool get_next_arg);
static void init_username();
static void add_int_to_prompt(int toadd);
+static int get_result_width(MYSQL_RES *res);
+static int get_field_disp_length(MYSQL_FIELD * field);
static int normalize_dbname(const char *line, char *buff, uint buff_size);
static int get_quote_count(const char *line);
@@ -459,7 +459,6 @@ static COMMANDS commands[] = {
{ "FORCE", 0, 0, 0, ""},
{ "FOREIGN", 0, 0, 0, ""},
{ "FOUND", 0, 0, 0, ""},
- { "FRAC_SECOND", 0, 0, 0, ""},
{ "FROM", 0, 0, 0, ""},
{ "FULL", 0, 0, 0, ""},
{ "FULLTEXT", 0, 0, 0, ""},
@@ -628,10 +627,6 @@ static COMMANDS commands[] = {
{ "QUARTER", 0, 0, 0, ""},
{ "QUERY", 0, 0, 0, ""},
{ "QUICK", 0, 0, 0, ""},
- { "RAID0", 0, 0, 0, ""},
- { "RAID_CHUNKS", 0, 0, 0, ""},
- { "RAID_CHUNKSIZE", 0, 0, 0, ""},
- { "RAID_TYPE", 0, 0, 0, ""},
{ "READ", 0, 0, 0, ""},
{ "READS", 0, 0, 0, ""},
{ "REAL", 0, 0, 0, ""},
@@ -704,7 +699,6 @@ static COMMANDS commands[] = {
{ "SQL_NO_CACHE", 0, 0, 0, ""},
{ "SQL_SMALL_RESULT", 0, 0, 0, ""},
{ "SQL_THREAD", 0, 0, 0, ""},
- { "SQL_TSI_FRAC_SECOND", 0, 0, 0, ""},
{ "SQL_TSI_SECOND", 0, 0, 0, ""},
{ "SQL_TSI_MINUTE", 0, 0, 0, ""},
{ "SQL_TSI_HOUR", 0, 0, 0, ""},
@@ -1071,6 +1065,10 @@ static void mysql_end_timer(ulong start_time,char *buff);
static void nice_time(double sec,char *buff,bool part_second);
extern "C" sig_handler mysql_end(int sig);
extern "C" sig_handler handle_sigint(int sig);
+#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
+static sig_handler window_resize(int sig);
+#endif
+
int main(int argc,char *argv[])
{
@@ -1120,7 +1118,11 @@ int main(int argc,char *argv[])
close(stdout_fileno_copy); /* Clean up dup(). */
}
- load_defaults("my",load_default_groups,&argc,&argv);
+ if (load_defaults("my",load_default_groups,&argc,&argv))
+ {
+ my_end(0);
+ exit(1);
+ }
defaults_argv=argv;
if (get_options(argc, (char **) argv))
{
@@ -1152,8 +1154,8 @@ int main(int argc,char *argv[])
if (sql_connect(current_host,current_db,current_user,opt_password,
opt_silent))
{
- quick=1; // Avoid history
- status.exit_status=1;
+ quick= 1; // Avoid history
+ status.exit_status= 1;
mysql_end(-1);
}
if (!status.batch)
@@ -1165,6 +1167,13 @@ int main(int argc,char *argv[])
signal(SIGINT, handle_sigint); // Catch SIGINT to clean up
signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up
+#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
+ /* Readline will call this if it installs a handler */
+ signal(SIGWINCH, window_resize);
+ /* call the SIGWINCH handler to get the default term width */
+ window_resize(0);
+#endif
+
put_info("Welcome to the MySQL monitor. Commands end with ; or \\g.",
INFO_INFO);
sprintf((char*) glob_buffer.ptr(),
@@ -1193,7 +1202,7 @@ int main(int argc,char *argv[])
strncmp(link_name, "/dev/null", 10) == 0)
{
/* The .mysql_history file is a symlink to /dev/null, don't use it */
- my_free(histfile, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(histfile);
histfile= 0;
}
}
@@ -1254,23 +1263,23 @@ sig_handler mysql_end(int sig)
glob_buffer.free();
old_buffer.free();
processed_prompt.free();
- my_free(server_version,MYF(MY_ALLOW_ZERO_PTR));
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
- my_free(opt_mysql_unix_port,MYF(MY_ALLOW_ZERO_PTR));
- my_free(histfile,MYF(MY_ALLOW_ZERO_PTR));
- my_free(histfile_tmp,MYF(MY_ALLOW_ZERO_PTR));
- my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
- my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
- my_free(current_user,MYF(MY_ALLOW_ZERO_PTR));
- my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
- my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
- my_free(default_prompt,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(server_version);
+ my_free(opt_password);
+ my_free(opt_mysql_unix_port);
+ my_free(histfile);
+ my_free(histfile_tmp);
+ my_free(current_db);
+ my_free(current_host);
+ my_free(current_user);
+ my_free(full_username);
+ my_free(part_username);
+ my_free(default_prompt);
#ifdef HAVE_SMEM
- my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(shared_memory_base_name);
#endif
- my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(current_prompt);
while (embedded_server_arg_count > 1)
- my_free(embedded_server_args[--embedded_server_arg_count],MYF(0));
+ my_free(embedded_server_args[--embedded_server_arg_count]);
mysql_server_end();
free_defaults(defaults_argv);
my_end(my_end_arg);
@@ -1337,16 +1346,22 @@ err:
}
+#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
+sig_handler window_resize(int sig)
+{
+ struct winsize window_size;
+
+ if (ioctl(fileno(stdin), TIOCGWINSZ, &window_size) == 0)
+ terminal_width= window_size.ws_col;
+}
+#endif
+
static struct my_option my_long_options[] =
{
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
0, 0, 0, 0, 0},
{"help", 'I', "Synonym for -?", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
0, 0, 0, 0, 0},
-#ifdef __NETWARE__
- {"autoclose", OPT_AUTO_CLOSE, "Automatically close the screen on exit for Netware.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-#endif
{"auto-rehash", OPT_AUTO_REHASH,
"Enable automatic rehashing. One doesn't need to use 'rehash' to get table "
"and field completion, but startup and reconnecting may take a longer time. "
@@ -1358,6 +1373,11 @@ static struct my_option my_long_options[] =
"completion. This gives a quicker start of mysql and disables rehashing "
"on reconnect.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"auto-vertical-output", OPT_AUTO_VERTICAL_OUTPUT,
+ "Automatically switch to vertical output mode if the result is wider "
+ "than the terminal width.",
+ &auto_vertical_output, &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
{"batch", 'B',
"Don't use history file. Disable interactive behavior. (Enables --silent.)",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -1393,6 +1413,10 @@ static struct my_option my_long_options[] =
&default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"delimiter", OPT_DELIMITER, "Delimiter to be used.", &delimiter_str,
&delimiter_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"enable_cleartext_plugin", OPT_ENABLE_CLEARTEXT_PLUGIN,
+ "Enable/disable the clear text authentication plugin.",
+ &opt_enable_cleartext_plugin, &opt_enable_cleartext_plugin,
+ 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"execute", 'e', "Execute command and quit. (Disables --force and history file.)", 0,
0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"vertical", 'E', "Print the output of a query (rows) vertically.",
@@ -1409,21 +1433,18 @@ static struct my_option my_long_options[] =
"is disabled by default.",
&named_cmds, &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
- {"no-named-commands", 'g',
- "Named commands are disabled. Use \\* form only, or use named commands "
- "only in the beginning of a line ending with a semicolon (;). Since "
- "version 10.9, the client now starts with this option ENABLED by default. "
- "Disable with '-G'. Long format commands still work from the first line. "
- "WARNING: option deprecated; use --disable-named-commands instead.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"ignore-spaces", 'i', "Ignore space after function names.",
&ignore_spaces, &ignore_spaces, 0, GET_BOOL, NO_ARG, 0, 0,
0, 0, 0, 0},
+ {"init-command", OPT_INIT_COMMAND,
+ "SQL Command to execute when connecting to MySQL server. Will "
+ "automatically be re-executed when reconnecting.",
+ &opt_init_command, &opt_init_command, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.",
- &opt_local_infile,
- &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ &opt_local_infile, &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"no-beep", 'b', "Turn off beep on error.", &opt_nobeep,
- &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"host", 'h', "Connect to host.", &current_host,
&current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"html", 'H', "Produce HTML output.", &opt_html, &opt_html,
@@ -1432,7 +1453,7 @@ static struct my_option my_long_options[] =
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"line-numbers", OPT_LINE_NUMBERS, "Write line numbers for errors.",
&line_numbers, &line_numbers, 0, GET_BOOL,
- NO_ARG, 1, 0, 0, 0, 0, 0},
+ NO_ARG, 1, 0, 0, 0, 0, 0},
{"skip-line-numbers", 'L', "Don't write line number for errors.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"unbuffered", 'n', "Flush buffer after each query.", &unbuffered,
@@ -1443,10 +1464,6 @@ static struct my_option my_long_options[] =
{"skip-column-names", 'N',
"Don't write column names in results.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"set-variable", 'O',
- "Change the value of a variable. Please note that this option is "
- "deprecated; you can set variables directly with --variable-name=value.",
- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"sigint-ignore", OPT_SIGINT_IGNORE, "Ignore SIGINT (CTRL-C).",
&opt_sigint_ignore, &opt_sigint_ignore, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -1462,10 +1479,6 @@ static struct my_option my_long_options[] =
"This option does not work in batch mode. Disable with --disable-pager. "
"This option is disabled by default.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
- {"no-pager", OPT_NOPAGER,
- "Disable pager and print to stdout. See interactive help (\\h) also. "
- "WARNING: option deprecated; use --disable-pager instead.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"password", 'p',
"Password to use when connecting to server. If password is not given it's asked from the tty.",
@@ -1515,9 +1528,6 @@ static struct my_option my_long_options[] =
"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},
- {"no-tee", OPT_NOTEE, "Disable outfile. See interactive help (\\h) also. "
- "WARNING: Option deprecated; use --disable-tee instead.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DONT_ALLOW_USER_CHANGE
{"user", 'u', "User for login if not current user.", &current_user,
&current_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -1563,17 +1573,19 @@ static struct my_option my_long_options[] =
{"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.",
&show_warnings, &show_warnings, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
+ {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
+ &opt_plugin_dir, &opt_plugin_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"default_auth", OPT_DEFAULT_AUTH,
+ "Default authentication client-side plugin to use.",
+ &opt_default_auth, &opt_default_auth, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static void usage(int version)
{
- /* Divert all help information on NetWare to logger screen. */
-#ifdef __NETWARE__
-#define printf consoleprintf
-#endif
-
#if defined(USE_LIBEDIT_INTERFACE)
const char* readline= "";
#else
@@ -1596,10 +1608,6 @@ static void usage(int version)
my_print_help(my_long_options);
print_defaults("my", load_default_groups);
my_print_variables(my_long_options);
- NETWARE_SET_SCREEN_MODE(1);
-#ifdef __NETWARE__
-#undef printf
-#endif
}
@@ -1608,18 +1616,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument)
{
switch(optid) {
-#ifdef __NETWARE__
- case OPT_AUTO_CLOSE:
- setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
- break;
-#endif
case OPT_CHARSETS_DIR:
strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir) - 1);
charsets_dir = mysql_charsets_dir;
break;
- case OPT_DEFAULT_CHARSET:
- default_charset_used= 1;
- break;
case OPT_DELIMITER:
if (argument == disabled_my_option)
{
@@ -1644,6 +1644,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case OPT_LOCAL_INFILE:
using_opt_local_infile=1;
break;
+ case OPT_ENABLE_CLEARTEXT_PLUGIN:
+ using_opt_enable_cleartext_plugin= TRUE;
+ break;
case OPT_TEE:
if (argument == disabled_my_option)
{
@@ -1653,11 +1656,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
else
init_tee(argument);
break;
- case OPT_NOTEE:
- WARN_DEPRECATED(VER_CELOSIA, "--no-tee", "--disable-tee");
- if (opt_outfile)
- end_tee();
- break;
case OPT_PAGER:
if (argument == disabled_my_option)
opt_nopager= 1;
@@ -1676,10 +1674,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
opt_nopager= 1;
}
break;
- case OPT_NOPAGER:
- WARN_DEPRECATED(VER_CELOSIA, "--no-pager", "--disable-pager");
- opt_nopager= 1;
- break;
case OPT_MYSQL_PROTOCOL:
#ifndef EMBEDDED_LIBRARY
opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
@@ -1723,25 +1717,19 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
if (!(status.line_buff= batch_readline_command(status.line_buff, argument)))
return 1;
break;
- case 'g':
- WARN_DEPRECATED(VER_CELOSIA, "-g, --no-named-commands", "--skip-named-commands");
- break;
case 'o':
if (argument == disabled_my_option)
one_database= 0;
else
one_database= skip_updates= 1;
break;
- case 'O':
- WARN_DEPRECATED(VER_CELOSIA, "-O, --set-variable", "--variable-name=value");
- break;
case 'p':
if (argument == disabled_my_option)
argument= (char*) ""; // Don't require password
if (argument)
{
char *start= argument;
- my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_password);
opt_password= my_strdup(argument, MYF(MY_FAE));
while (*argument) *argument++= 'x'; // Destroy argument
if (*start)
@@ -1830,10 +1818,6 @@ static int get_options(int argc, char **argv)
connect_flag= 0; /* Not in interactive mode */
}
- if (strcmp(default_charset, charset_info->csname) &&
- !(charset_info= get_charset_by_csname(default_charset,
- MY_CS_PRIMARY, MYF(MY_WME))))
- exit(1);
if (argc > 1)
{
usage(0);
@@ -1842,7 +1826,7 @@ static int get_options(int argc, char **argv)
if (argc == 1)
{
skip_updates= 0;
- my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(current_db);
current_db= my_strdup(*argv, MYF(MY_WME));
}
if (tty_password)
@@ -1860,10 +1844,6 @@ static int get_options(int argc, char **argv)
static int read_and_execute(bool interactive)
{
-#if defined(__NETWARE__)
- char linebuffer[254];
- String buffer;
-#endif
#if defined(__WIN__)
String tmpbuf;
String buffer;
@@ -1908,18 +1888,8 @@ static int read_and_execute(bool interactive)
if (opt_outfile && glob_buffer.is_empty())
fflush(OUTFILE);
-#if defined(__WIN__) || defined(__NETWARE__)
+#if defined(__WIN__)
tee_fputs(prompt, stdout);
-#if defined(__NETWARE__)
- line=fgets(linebuffer, sizeof(linebuffer)-1, stdin);
- /* Remove the '\n' */
- if (line)
- {
- char *p = strrchr(line, '\n');
- if (p != NULL)
- *p = '\0';
- }
-#else
if (!tmpbuf.is_alloced())
tmpbuf.alloc(65535);
tmpbuf.length(0);
@@ -1940,12 +1910,11 @@ static int read_and_execute(bool interactive)
*/
if (line)
line= buffer.c_ptr();
-#endif /* __NETWARE__ */
#else
if (opt_outfile)
fputs(prompt, OUTFILE);
line= readline(prompt);
-#endif /* defined(__WIN__) || defined(__NETWARE__) */
+#endif /* defined(__WIN__) */
/*
When Ctrl+d or Ctrl+z is pressed, the line may be NULL on some OS
@@ -1998,10 +1967,8 @@ static int read_and_execute(bool interactive)
}
}
-#if defined(__WIN__) || defined(__NETWARE__)
- buffer.free();
-#endif
#if defined(__WIN__)
+ buffer.free();
tmpbuf.free();
#endif
@@ -2345,8 +2312,10 @@ static bool add_line(String &buffer,char *line,char *in_string,
#ifdef HAVE_READLINE
+C_MODE_START
static char *new_command_generator(const char *text, int);
-extern "C" char **new_mysql_completion (const char *text, int start, int end);
+static char **new_mysql_completion(const char *text, int start, int end);
+C_MODE_END
/*
Tell the GNU Readline library how to complete. We want to try to complete
@@ -2478,9 +2447,9 @@ static void initialize_readline (char *name)
array of matches, or NULL if there aren't any.
*/
-char **new_mysql_completion (const char *text,
- int start __attribute__((unused)),
- int end __attribute__((unused)))
+static char **new_mysql_completion(const char *text,
+ int start __attribute__((unused)),
+ int end __attribute__((unused)))
{
if (!status.batch && !quick)
#if defined(USE_NEW_READLINE_INTERFACE)
@@ -2746,7 +2715,7 @@ static void get_current_db()
if (one_database)
return;
- my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(current_db);
current_db= NULL;
/* In case of error below current_db will be NULL */
if (!mysql_query(&mysql, "SELECT DATABASE()") &&
@@ -2977,7 +2946,6 @@ com_charset(String *buffer __attribute__((unused)), char *line)
charset_info= new_cs;
mysql_set_character_set(&mysql, charset_info->csname);
default_charset= (char *)charset_info->csname;
- default_charset_used= 1;
put_info("Charset changed", INFO_INFO);
}
else put_info("Charset is not found", INFO_INFO);
@@ -3104,7 +3072,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
print_table_data_html(result);
else if (opt_xml)
print_table_data_xml(result);
- else if (vertical)
+ else if (vertical || (auto_vertical_output && (terminal_width < get_result_width(result))))
print_table_data_vertically(result);
else if (opt_silent && verbose <= 2 && !output_tables)
print_tab_data(result);
@@ -3435,6 +3403,65 @@ print_table_data(MYSQL_RES *result)
my_afree((uchar*) num_flag);
}
+/**
+ Return the length of a field after it would be rendered into text.
+
+ This doesn't know or care about multibyte characters. Assume we're
+ using such a charset. We can't know that all of the upcoming rows
+ for this column will have bytes that each render into some fraction
+ of a character. It's at least possible that a row has bytes that
+ all render into one character each, and so the maximum length is
+ still the number of bytes. (Assumption 1: This can't be better
+ because we can never know the number of characters that the DB is
+ going to send -- only the number of bytes. 2: Chars <= Bytes.)
+
+ @param field Pointer to a field to be inspected
+
+ @returns number of character positions to be used, at most
+*/
+static int get_field_disp_length(MYSQL_FIELD *field)
+{
+ uint length= column_names ? field->name_length : 0;
+
+ if (quick)
+ length= max(length, field->length);
+ else
+ length= max(length, field->max_length);
+
+ if (length < 4 && !IS_NOT_NULL(field->flags))
+ length= 4; /* Room for "NULL" */
+
+ return length;
+}
+
+/**
+ For a new result, return the max number of characters that any
+ upcoming row may return.
+
+ @param result Pointer to the result to judge
+
+ @returns The max number of characters in any row of this result
+*/
+static int get_result_width(MYSQL_RES *result)
+{
+ unsigned int len= 0;
+ MYSQL_FIELD *field;
+ MYSQL_FIELD_OFFSET offset;
+
+#ifndef DBUG_OFF
+ offset= mysql_field_tell(result);
+ DBUG_ASSERT(offset == 0);
+#else
+ offset= 0;
+#endif
+
+ while ((field= mysql_fetch_field(result)) != NULL)
+ len+= get_field_disp_length(field) + 3; /* plus bar, space, & final space */
+
+ (void) mysql_field_seek(result, offset);
+
+ return len + 1; /* plus final bar. */
+}
static void
tee_print_sized_data(const char *data, unsigned int data_length, unsigned int total_bytes_to_send, bool right_justified)
@@ -3614,7 +3641,7 @@ static void print_warnings()
mysql_store_result_for_lazy(&result);
/* Bail out when no warnings */
- if (!(num_rows= mysql_num_rows(result)))
+ if (!result || !(num_rows= mysql_num_rows(result)))
goto end;
cur= mysql_fetch_row(result);
@@ -3912,8 +3939,6 @@ static int
com_quit(String *buffer __attribute__((unused)),
char *line __attribute__((unused)))
{
- /* let the screen auto close on a normal shutdown */
- NETWARE_SET_SCREEN_MODE(SCR_AUTOCLOSE_ON_EXIT);
status.exit_status=0;
return 1;
}
@@ -3991,12 +4016,12 @@ com_connect(String *buffer, char *line)
tmp= get_arg(buff, 0);
if (tmp && *tmp)
{
- my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(current_db);
current_db= my_strdup(tmp, MYF(MY_WME));
tmp= get_arg(buff, 1);
if (tmp)
{
- my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(current_host);
current_host=my_strdup(tmp,MYF(MY_WME));
}
}
@@ -4184,7 +4209,7 @@ com_use(String *buffer __attribute__((unused)), char *line)
if (mysql_select_db(&mysql,tmp))
return put_error(&mysql);
}
- my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(current_db);
current_db=my_strdup(tmp,MYF(MY_WME));
#ifdef HAVE_READLINE
if (select_db > 1)
@@ -4356,6 +4381,8 @@ sql_real_connect(char *host,char *database,char *user,char *password,
mysql_close(&mysql);
}
mysql_init(&mysql);
+ if (opt_init_command)
+ mysql_options(&mysql, MYSQL_INIT_COMMAND, opt_init_command);
if (opt_connect_timeout)
{
uint timeout=opt_connect_timeout;
@@ -4368,7 +4395,7 @@ sql_real_connect(char *host,char *database,char *user,char *password,
mysql_options(&mysql, MYSQL_SECURE_AUTH, (char *) &opt_secure_auth);
if (using_opt_local_infile)
mysql_options(&mysql,MYSQL_OPT_LOCAL_INFILE, (char*) &opt_local_infile);
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
@@ -4389,11 +4416,22 @@ sql_real_connect(char *host,char *database,char *user,char *password,
select_limit,max_join_size);
mysql_options(&mysql, MYSQL_INIT_COMMAND, init_command);
}
- if (default_charset_used)
- mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
+
+ mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
+
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(&mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (opt_default_auth && *opt_default_auth)
+ mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
+
+ if (using_opt_enable_cleartext_plugin)
+ mysql_options(&mysql, MYSQL_ENABLE_CLEARTEXT_PLUGIN,
+ (char*) &opt_enable_cleartext_plugin);
+
if (!mysql_real_connect(&mysql, host, user, password,
- database, opt_mysql_port, opt_mysql_unix_port,
- connect_flag | CLIENT_MULTI_STATEMENTS))
+ database, opt_mysql_port, opt_mysql_unix_port,
+ connect_flag | CLIENT_MULTI_STATEMENTS))
{
if (!silent ||
(mysql_errno(&mysql) != CR_CONN_HOST_ERROR &&
@@ -4405,6 +4443,9 @@ sql_real_connect(char *host,char *database,char *user,char *password,
}
return -1; // Retryable
}
+
+ charset_info= mysql.charset;
+
connected=1;
#ifndef EMBEDDED_LIBRARY
mysql.reconnect= debug_info_flag; // We want to know if this happens
@@ -4485,12 +4526,12 @@ com_status(String *buffer __attribute__((unused)),
mysql_free_result(result);
}
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
if ((status_str= mysql_get_ssl_cipher(&mysql)))
tee_fprintf(stdout, "SSL:\t\t\tCipher in use is %s\n",
status_str);
else
-#endif /* HAVE_OPENSSL */
+#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
tee_puts("SSL:\t\t\tNot in use", stdout);
if (skip_updates)
@@ -4712,7 +4753,6 @@ void tee_fprintf(FILE *file, const char *fmt, ...)
{
va_list args;
- NETWARE_YIELD;
va_start(args, fmt);
(void) vfprintf(file, fmt, args);
va_end(args);
@@ -4728,7 +4768,6 @@ void tee_fprintf(FILE *file, const char *fmt, ...)
void tee_fputs(const char *s, FILE *file)
{
- NETWARE_YIELD;
fputs(s, file);
if (opt_outfile)
fputs(s, OUTFILE);
@@ -4737,7 +4776,6 @@ void tee_fputs(const char *s, FILE *file)
void tee_puts(const char *s, FILE *file)
{
- NETWARE_YIELD;
fputs(s, file);
fputc('\n', file);
if (opt_outfile)
@@ -4754,7 +4792,7 @@ void tee_putc(int c, FILE *file)
putc(c, OUTFILE);
}
-#if defined(__WIN__) || defined(__NETWARE__)
+#if defined(__WIN__)
#include <time.h>
#else
#include <sys/times.h>
@@ -4766,8 +4804,8 @@ void tee_putc(int c, FILE *file)
static ulong start_timer(void)
{
-#if defined(__WIN__) || defined(__NETWARE__)
- return clock();
+#if defined(__WIN__)
+ return clock();
#else
struct tms tms_tmp;
return times(&tms_tmp);
@@ -5000,8 +5038,8 @@ static void add_int_to_prompt(int toadd)
static void init_username()
{
- my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
- my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(full_username);
+ my_free(part_username);
MYSQL_RES *result;
LINT_INIT(result);
@@ -5020,7 +5058,7 @@ static int com_prompt(String *buffer __attribute__((unused)),
{
char *ptr=strchr(line, ' ');
prompt_counter = 0;
- my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(current_prompt);
current_prompt=my_strdup(ptr ? ptr+1 : default_prompt,MYF(MY_WME));
if (!ptr)
tee_fprintf(stdout, "Returning to default PROMPT of %s\n", default_prompt);
@@ -5028,17 +5066,3 @@ static int com_prompt(String *buffer __attribute__((unused)),
tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
return 0;
}
-
-#ifndef EMBEDDED_LIBRARY
-/* Keep sql_string library happy */
-
-void *sql_alloc(size_t Size)
-{
- return my_malloc(Size,MYF(MY_WME));
-}
-
-void sql_element_free(void *ptr)
-{
- my_free(ptr,MYF(0));
-}
-#endif /* EMBEDDED_LIBRARY */
diff --git a/client/mysql_plugin.c b/client/mysql_plugin.c
new file mode 100644
index 00000000000..bbb44678f51
--- /dev/null
+++ b/client/mysql_plugin.c
@@ -0,0 +1,1205 @@
+/*
+ Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+
+ 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
+*/
+
+#include <m_string.h>
+#include <mysql.h>
+#include <my_getopt.h>
+#include <my_dir.h>
+#include <my_global.h>
+#include <stdio.h>
+#include <string.h>
+
+
+#define SHOW_VERSION "1.0.0"
+#define PRINT_VERSION do { printf("%s Ver %s Distrib %s\n", \
+ my_progname, SHOW_VERSION, MYSQL_SERVER_VERSION); \
+ } while(0)
+
+/* Global variables. */
+static uint my_end_arg= 0;
+static uint opt_verbose=0;
+static uint opt_no_defaults= 0;
+static uint opt_print_defaults= 0;
+static char *opt_datadir=0, *opt_basedir=0,
+ *opt_plugin_dir=0, *opt_plugin_ini=0,
+ *opt_mysqld=0, *opt_my_print_defaults=0;
+static char bootstrap[FN_REFLEN];
+
+
+/* plugin struct */
+struct st_plugin
+{
+ const char *name; /* plugin name */
+ const char *so_name; /* plugin so (library) name */
+ const char *components[16]; /* components to load */
+} plugin_data;
+
+
+/* Options */
+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},
+ {"basedir", 'b', "The basedir for the server.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"datadir", 'd', "The datadir for the server.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"plugin-dir", 'p', "The plugin dir for the server.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"plugin-ini", 'i', "Read plugin information from configuration file "
+ "specified instead of from <plugin-dir>/<plugin_name>.ini.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"no-defaults", 'n', "Do not read values from configuration file.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"print-defaults", 'P', "Show default values from configuration file.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"mysqld", 'm', "Path to mysqld executable. Example: /sbin/temp1/mysql/bin",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"my-print-defaults", 'f', "Path to my_print_defaults executable. "
+ "Example: /source/temp11/extra",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v',
+ "More verbose output; you can use this multiple times to get even more "
+ "verbose output.",
+ 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},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+
+/* Methods */
+static int process_options(int argc, char *argv[], char *operation);
+static int check_access();
+static int find_tool(const char *tool_name, char *tool_path);
+static int find_plugin(char *tp_path);
+static int build_bootstrap_file(char *operation, char *bootstrap);
+static int dump_bootstrap_file(char *bootstrap_file);
+static int bootstrap_server(char *server_path, char *bootstrap_file);
+
+
+int main(int argc,char *argv[])
+{
+ int error= 0;
+ char tp_path[FN_REFLEN];
+ char server_path[FN_REFLEN];
+ char operation[16];
+
+ MY_INIT(argv[0]);
+ plugin_data.name= 0; // initialize name
+
+ /*
+ The following operations comprise the method for enabling or disabling
+ a plugin. We begin by processing the command options then check the
+ directories specified for --datadir, --basedir, --plugin-dir, and
+ --plugin-ini (if specified). If the directories are Ok, we then look
+ for the mysqld executable and the plugin soname. Finally, we build a
+ bootstrap command file for use in bootstraping the server.
+
+ If any step fails, the method issues an error message and the tool exits.
+
+ 1) Parse, execute, and verify command options.
+ 2) Check access to directories.
+ 3) Look for mysqld executable.
+ 4) Look for the plugin.
+ 5) Build a bootstrap file with commands to enable or disable plugin.
+
+ */
+ if ((error= process_options(argc, argv, operation)) ||
+ (error= check_access()) ||
+ (error= find_tool("mysqld" FN_EXEEXT, server_path)) ||
+ (error= find_plugin(tp_path)) ||
+ (error= build_bootstrap_file(operation, bootstrap)))
+ goto exit;
+
+ /* Dump the bootstrap file if --verbose specified. */
+ if (opt_verbose && ((error= dump_bootstrap_file(bootstrap))))
+ goto exit;
+
+ /* Start the server in bootstrap mode and execute bootstrap commands */
+ error= bootstrap_server(server_path, bootstrap);
+
+exit:
+ /* Remove file */
+ my_delete(bootstrap, MYF(0));
+ if (opt_verbose && error == 0)
+ {
+ printf("# Operation succeeded.\n");
+ }
+
+ my_end(my_end_arg);
+ exit(error ? 1 : 0);
+ return 0; /* No compiler warnings */
+}
+
+
+/**
+ Get a temporary file name.
+
+ @param[out] filename The file name of the temporary file
+ @param[in] ext An extension for the file (optional)
+
+ @retval int error = 1, success = 0
+*/
+
+static int make_tempfile(char *filename, const char *ext)
+{
+ int fd= 0;
+
+ if ((fd=create_temp_file(filename, NullS, ext, O_CREAT | O_WRONLY,
+ MYF(MY_WME))) < 0)
+ {
+ fprintf(stderr, "ERROR: Cannot generate temporary file. Error code: %d.\n",
+ fd);
+ return 1;
+ }
+ my_close(fd, MYF(0));
+ return 0;
+}
+
+
+/**
+ Get the value of an option from a string read from my_print_defaults output.
+
+ @param[in] line The line (string) read from the file
+ @param[in] item The option to search for (e.g. --datadir)
+
+ @returns NULL if not found, string containing value if found
+*/
+
+static char *get_value(char *line, const char *item)
+{
+ char *destination= 0;
+ int item_len= (int)strlen(item);
+ int line_len = (int)strlen(line);
+
+ if ((strncasecmp(line, item, item_len) == 0))
+ {
+ int start= 0;
+ char *s= 0;
+
+ s = line + item_len + 1;
+ destination= my_strndup(s, line_len - start, MYF(MY_FAE));
+ destination[line_len - item_len - 2]= 0;
+ }
+ return destination;
+}
+
+
+/**
+ Run a command in a shell.
+
+ This function will attempt to execute the command specified by using the
+ popen() method to open a shell and execute the command passed and store the
+ output in a result file. If the --verbose option was specified, it will open
+ the result file and print the contents to stdout.
+
+ @param[in] cmd The command to execute.
+ @param[in] mode The mode for popen() (e.g. "r", "w", "rw")
+
+ @return int error code or 0 for success.
+*/
+
+static int run_command(char* cmd, const char *mode)
+{
+ char buf[512]= {0};
+ FILE *res_file;
+ int error;
+
+ if (!(res_file= popen(cmd, mode)))
+ return -1;
+
+ if (opt_verbose)
+ {
+ while (fgets(buf, sizeof(buf), res_file))
+ {
+ fprintf(stdout, "%s", buf);
+ }
+ }
+ error= pclose(res_file);
+ return error;
+}
+
+
+#ifdef __WIN__
+/**
+ Check to see if there are spaces in a path.
+
+ @param[in] path The Windows path to examine.
+
+ @retval int spaces found = 1, no spaces = 0
+*/
+static int has_spaces(const char *path)
+{
+ if (strchr(path, ' ') != NULL)
+ return 1;
+ return 0;
+}
+
+
+/**
+ Convert a Unix path to a Windows path.
+
+ @param[in] path The Windows path to examine.
+
+ @returns string containing path with / changed to \\
+*/
+static char *convert_path(const char *argument)
+{
+ /* Convert / to \\ to make Windows paths */
+ char *winfilename= my_strdup(argument, MYF(MY_FAE));
+ char *pos, *end;
+ int length= strlen(argument);
+
+ for (pos= winfilename, end= pos+length ; pos < end ; pos++)
+ {
+ if (*pos == '/')
+ {
+ *pos= '\\';
+ }
+ }
+ return winfilename;
+}
+
+
+/**
+ Add quotes if the path has spaces in it.
+
+ @param[in] path The Windows path to examine.
+
+ @returns string containing excaped quotes if spaces found in path
+*/
+static char *add_quotes(const char *path)
+{
+ char windows_cmd_friendly[FN_REFLEN];
+
+ if (has_spaces(path))
+ snprintf(windows_cmd_friendly, sizeof(windows_cmd_friendly),
+ "\"%s\"", path);
+ else
+ snprintf(windows_cmd_friendly, sizeof(windows_cmd_friendly),
+ "%s", path);
+ return my_strdup(windows_cmd_friendly, MYF(MY_FAE));
+}
+#endif
+
+
+/**
+ Get the default values from the my.cnf file.
+
+ This method gets the default values for the following parameters:
+
+ --datadir
+ --basedir
+ --plugin-dir
+ --plugin-ini
+
+ These values are used if the user has not specified a value.
+
+ @retval int error = 1, success = 0
+*/
+
+static int get_default_values()
+{
+ char tool_path[FN_REFLEN];
+ char defaults_cmd[FN_REFLEN];
+ char defaults_file[FN_REFLEN];
+ char line[FN_REFLEN];
+ int error= 0;
+ int ret= 0;
+ FILE *file= 0;
+
+ bzero(tool_path, FN_REFLEN);
+ if ((error= find_tool("my_print_defaults" FN_EXEEXT, tool_path)))
+ goto exit;
+ else
+ {
+ if ((error= make_tempfile(defaults_file, "txt")))
+ goto exit;
+
+#ifdef __WIN__
+ {
+ char *format_str= 0;
+
+ if (has_spaces(tool_path) || has_spaces(defaults_file))
+ format_str = "\"%s mysqld > %s\"";
+ else
+ format_str = "%s mysqld > %s";
+
+ snprintf(defaults_cmd, sizeof(defaults_cmd), format_str,
+ add_quotes(tool_path), add_quotes(defaults_file));
+ if (opt_verbose)
+ {
+ printf("# my_print_defaults found: %s\n", tool_path);
+ }
+ }
+#else
+ snprintf(defaults_cmd, sizeof(defaults_cmd),
+ "%s mysqld > %s", tool_path, defaults_file);
+#endif
+
+ /* Execute the command */
+ if (opt_verbose)
+ {
+ printf("# Command: %s\n", defaults_cmd);
+ }
+ error= run_command(defaults_cmd, "r");
+ if (error)
+ {
+ fprintf(stderr, "ERROR: my_print_defaults failed. Error code: %d.\n",
+ ret);
+ goto exit;
+ }
+ /* Now open the file and read the defaults we want. */
+ file= fopen(defaults_file, "r");
+ while (fgets(line, FN_REFLEN, file) != NULL)
+ {
+ char *value= 0;
+
+ if ((opt_datadir == 0) && ((value= get_value(line, "--datadir"))))
+ {
+ opt_datadir= my_strdup(value, MYF(MY_FAE));
+ }
+ if ((opt_basedir == 0) && ((value= get_value(line, "--basedir"))))
+ {
+ opt_basedir= my_strdup(value, MYF(MY_FAE));
+ }
+ if ((opt_plugin_dir == 0) && ((value= get_value(line, "--plugin_dir"))))
+ {
+ opt_plugin_dir= my_strdup(value, MYF(MY_FAE));
+ }
+ if ((opt_plugin_ini == 0) && ((value= get_value(line, "--plugin_ini"))))
+ {
+ opt_plugin_ini= my_strdup(value, MYF(MY_FAE));
+ }
+ }
+ }
+exit:
+ if (file)
+ {
+ fclose(file);
+ /* Remove file */
+ my_delete(defaults_file, MYF(0));
+ }
+ return error;
+}
+
+
+/**
+ Print usage.
+*/
+
+static void usage(void)
+{
+ PRINT_VERSION;
+ puts("Copyright (c) 2011, Oracle and/or its affiliates. "
+ "All rights reserved.\n");
+ puts("Enable or disable plugins.");
+ printf("\nUsage: %s [options] <plugin> ENABLE|DISABLE\n\nOptions:\n",
+ my_progname);
+ my_print_help(my_long_options);
+ puts("\n");
+}
+
+
+/**
+ Print the default values as read from the my.cnf file.
+
+ This method displays the default values for the following parameters:
+
+ --datadir
+ --basedir
+ --plugin-dir
+ --plugin-ini
+
+*/
+
+static void print_default_values(void)
+{
+ printf("%s would have been started with the following arguments:\n",
+ my_progname);
+ get_default_values();
+ if (opt_datadir)
+ {
+ printf("--datadir=%s ", opt_datadir);
+ }
+ if (opt_basedir)
+ {
+ printf("--basedir=%s ", opt_basedir);
+ }
+ if (opt_plugin_dir)
+ {
+ printf("--plugin_dir=%s ", opt_plugin_dir);
+ }
+ if (opt_plugin_ini)
+ {
+ printf("--plugin_ini=%s ", opt_plugin_ini);
+ }
+ if (opt_mysqld)
+ {
+ printf("--mysqld=%s ", opt_mysqld);
+ }
+ if (opt_my_print_defaults)
+ {
+ printf("--my_print_defaults=%s ", opt_my_print_defaults);
+ }
+ printf("\n");
+}
+
+
+/**
+ Process the arguments and identify an option and store its value.
+
+ @param[in] optid The single character shortcut for the argument.
+ @param[in] my_option Structure of legal options.
+ @param[in] argument The argument value to process.
+*/
+
+static my_bool
+get_one_option(int optid,
+ const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch(optid) {
+ case 'n':
+ opt_no_defaults++;
+ break;
+ case 'P':
+ opt_print_defaults++;
+ print_default_values();
+ break;
+ case 'v':
+ opt_verbose++;
+ break;
+ case 'V':
+ PRINT_VERSION;
+ exit(0);
+ break;
+ case '?':
+ case 'I': /* Info */
+ usage();
+ exit(0);
+ case 'd':
+ opt_datadir= my_strdup(argument, MYF(MY_FAE));
+ break;
+ case 'b':
+ opt_basedir= my_strdup(argument, MYF(MY_FAE));
+ break;
+ case 'p':
+ opt_plugin_dir= my_strdup(argument, MYF(MY_FAE));
+ break;
+ case 'i':
+ opt_plugin_ini= my_strdup(argument, MYF(MY_FAE));
+ break;
+ case 'm':
+ opt_mysqld= my_strdup(argument, MYF(MY_FAE));
+ break;
+ case 'f':
+ opt_my_print_defaults= my_strdup(argument, MYF(MY_FAE));
+ break;
+ }
+ return 0;
+}
+
+
+/**
+ Check to see if a file exists.
+
+ @param[in] filename File to locate.
+
+ @retval int file not found = 1, file found = 0
+*/
+
+static int file_exists(char * filename)
+{
+ MY_STAT stat_arg;
+
+ if (!my_stat(filename, &stat_arg, MYF(0)))
+ {
+ return 0;
+ }
+ return 1;
+}
+
+
+/**
+ Search a specific path and sub directory for a file name.
+
+ @param[in] base_path Original path to use.
+ @param[in] tool_name Name of the tool to locate.
+ @param[in] subdir The sub directory to search.
+ @param[out] tool_path If tool found, return complete path.
+
+ @retval int error = 1, success = 0
+*/
+
+static int search_dir(const char * base_path, const char *tool_name,
+ const char *subdir, char *tool_path)
+{
+ char new_path[FN_REFLEN];
+ char source_path[FN_REFLEN];
+
+ strcpy(source_path, base_path);
+ strcat(source_path, subdir);
+ fn_format(new_path, tool_name, source_path, "", MY_UNPACK_FILENAME);
+ if (file_exists(new_path))
+ {
+ strcpy(tool_path, new_path);
+ return 1;
+ }
+ return 0;
+}
+
+
+/**
+ Search known common paths and sub directories for a file name.
+
+ @param[in] base_path Original path to use.
+ @param[in] tool_name Name of the tool to locate.
+ @param[out] tool_path If tool found, return complete path.
+
+ @retval int error = 1, success = 0
+*/
+
+static int search_paths(const char *base_path, const char *tool_name,
+ char *tool_path)
+{
+ int i= 0;
+
+ static const char *paths[]= {
+ "", "/share/", "/scripts/", "/bin/", "/sbin/", "/libexec/",
+ "/mysql/", "/sql/",
+ };
+ for (i = 0 ; i < (int)array_elements(paths); i++)
+ {
+ if (search_dir(base_path, tool_name, paths[i], tool_path))
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/**
+ Read the plugin ini file.
+
+ This function attempts to read the plugin config file from the plugin_dir
+ path saving the data in the the st_plugin structure. If the file is not
+ found or the file cannot be read, an error is generated.
+
+ @retval int error = 1, success = 0
+*/
+
+static int load_plugin_data(char *plugin_name, char *config_file)
+{
+ FILE *file_ptr;
+ char path[FN_REFLEN];
+ char line[1024];
+ char *reason= 0;
+ char *res;
+ int i= -1;
+
+ if (opt_plugin_ini == 0)
+ {
+ fn_format(path, config_file, opt_plugin_dir, "", MYF(0));
+ opt_plugin_ini= my_strdup(path, MYF(MY_FAE));
+ }
+ if (!file_exists(opt_plugin_ini))
+ {
+ reason= (char *)"File does not exist.";
+ goto error;
+ }
+
+ file_ptr= fopen(opt_plugin_ini, "r");
+ if (file_ptr == NULL)
+ {
+ reason= (char *)"Cannot open file.";
+ goto error;
+ }
+
+ /* save name */
+ plugin_data.name= my_strdup(plugin_name, MYF(MY_WME));
+
+ /* Read plugin components */
+ while (i < 16)
+ {
+ res= fgets(line, sizeof(line), file_ptr);
+ /* strip /n */
+ if (line[strlen(line)-1] == '\n')
+ {
+ line[strlen(line)-1]= '\0';
+ }
+ if (res == NULL)
+ {
+ if (i < 1)
+ {
+ reason= (char *)"Bad format in plugin configuration file.";
+ fclose(file_ptr);
+ goto error;
+ }
+ break;
+ }
+ if ((line[0] == '#') || (line[0] == '\n')) // skip comment and blank lines
+ {
+ continue;
+ }
+ if (i == -1) // if first pass, read this line as so_name
+ {
+ /* Add proper file extension for soname */
+ strcat(line, FN_SOEXT);
+ /* save so_name */
+ plugin_data.so_name= my_strdup(line, MYF(MY_WME|MY_ZEROFILL));
+ i++;
+ }
+ else
+ {
+ if (strlen(line) > 0)
+ {
+ plugin_data.components[i]= my_strdup(line, MYF(MY_WME));
+ i++;
+ }
+ else
+ {
+ plugin_data.components[i]= NULL;
+ }
+ }
+ }
+
+ fclose(file_ptr);
+ return 0;
+
+error:
+ fprintf(stderr, "ERROR: Cannot read plugin config file %s. %s\n",
+ plugin_name, reason);
+ return 1;
+}
+
+
+/**
+ Check the options for validity.
+
+ This function checks the arguments for validity issuing the appropriate
+ error message if arguments are missing or invalid. On success, @operation
+ is set to either "ENABLE" or "DISABLE".
+
+ @param[in] argc The number of arguments.
+ @param[in] argv The arguments.
+ @param[out] operation The operation chosen (enable|disable)
+
+ @retval int error = 1, success = 0
+*/
+
+static int check_options(int argc, char **argv, char *operation)
+{
+ int i= 0; // loop counter
+ int num_found= 0; // number of options found (shortcut loop)
+ char config_file[FN_REFLEN]; // configuration file name
+ char plugin_name[FN_REFLEN]; // plugin name
+
+ /* Form prefix strings for the options. */
+ const char *basedir_prefix = "--basedir=";
+ int basedir_len= strlen(basedir_prefix);
+ const char *datadir_prefix = "--datadir=";
+ int datadir_len= strlen(datadir_prefix);
+ const char *plugin_dir_prefix = "--plugin_dir=";
+ int plugin_dir_len= strlen(plugin_dir_prefix);
+
+ strcpy(plugin_name, "");
+ for (i = 0; i < argc && num_found < 5; i++)
+ {
+
+ if (!argv[i])
+ {
+ continue;
+ }
+ if ((strcasecmp(argv[i], "ENABLE") == 0) ||
+ (strcasecmp(argv[i], "DISABLE") == 0))
+ {
+ strcpy(operation, argv[i]);
+ num_found++;
+ }
+ else if ((strncasecmp(argv[i], basedir_prefix, basedir_len) == 0) &&
+ !opt_basedir)
+ {
+ opt_basedir= my_strndup(argv[i]+basedir_len,
+ strlen(argv[i])-basedir_len, MYF(MY_FAE));
+ num_found++;
+ }
+ else if ((strncasecmp(argv[i], datadir_prefix, datadir_len) == 0) &&
+ !opt_datadir)
+ {
+ opt_datadir= my_strndup(argv[i]+datadir_len,
+ strlen(argv[i])-datadir_len, MYF(MY_FAE));
+ num_found++;
+ }
+ else if ((strncasecmp(argv[i], plugin_dir_prefix, plugin_dir_len) == 0) &&
+ !opt_plugin_dir)
+ {
+ opt_plugin_dir= my_strndup(argv[i]+plugin_dir_len,
+ strlen(argv[i])-plugin_dir_len, MYF(MY_FAE));
+ num_found++;
+ }
+ /* read the plugin config file and check for match against argument */
+ else
+ {
+ strcpy(plugin_name, argv[i]);
+ strcpy(config_file, argv[i]);
+ strcat(config_file, ".ini");
+ }
+ }
+
+ if (!opt_basedir)
+ {
+ fprintf(stderr, "ERROR: Missing --basedir option.\n");
+ return 1;
+ }
+
+ if (!opt_datadir)
+ {
+ fprintf(stderr, "ERROR: Missing --datadir option.\n");
+ return 1;
+ }
+
+ if (!opt_plugin_dir)
+ {
+ fprintf(stderr, "ERROR: Missing --plugin_dir option.\n");
+ return 1;
+ }
+ /* If a plugin was specified, read the config file. */
+ else if (strlen(plugin_name) > 0)
+ {
+ if (load_plugin_data(plugin_name, config_file))
+ {
+ return 1;
+ }
+ if (strcasecmp(plugin_data.name, plugin_name) != 0)
+ {
+ fprintf(stderr, "ERROR: plugin name requested does not match config "
+ "file data.\n");
+ return 1;
+ }
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: No plugin specified.\n");
+ return 1;
+ }
+
+ if ((strlen(operation) == 0))
+ {
+ fprintf(stderr, "ERROR: missing operation. Please specify either "
+ "'<plugin> ENABLE' or '<plugin> DISABLE'.\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/**
+ Parse, execute, and verify command options.
+
+ This method handles all of the option processing including the optional
+ features for displaying data (--print-defaults, --help ,etc.) that do not
+ result in an attempt to ENABLE or DISABLE of a plugin.
+
+ @param[in] arc Count of arguments
+ @param[in] argv Array of arguments
+ @param[out] operation Operation (ENABLE or DISABLE)
+
+ @retval int error = 1, success = 0, exit program = -1
+*/
+
+static int process_options(int argc, char *argv[], char *operation)
+{
+ int error= 0;
+ int i= 0;
+
+ /* Parse and execute command-line options */
+ if ((error= handle_options(&argc, &argv, my_long_options, get_one_option)))
+ goto exit;
+
+ /* If the print defaults option used, exit. */
+ if (opt_print_defaults)
+ {
+ error= -1;
+ goto exit;
+ }
+
+ /* Add a trailing directory separator if not present */
+ if (opt_basedir)
+ {
+ i= (int)strlength(opt_basedir);
+ if (opt_basedir[i-1] != FN_LIBCHAR || opt_basedir[i-1] != FN_LIBCHAR2)
+ {
+ char buff[FN_REFLEN];
+
+ strncpy(buff, opt_basedir, sizeof(buff) - 1);
+#ifdef __WIN__
+ strncat(buff, "/", sizeof(buff) - strlen(buff) - 1);
+#else
+ strncat(buff, FN_DIRSEP, sizeof(buff) - strlen(buff) - 1);
+#endif
+ buff[sizeof(buff) - 1]= 0;
+ my_delete(opt_basedir, MYF(0));
+ opt_basedir= my_strdup(buff, MYF(MY_FAE));
+ }
+ }
+
+ /*
+ If the user did not specify the option to skip loading defaults from a
+ config file and the required options are not present or there was an error
+ generated when the defaults were read from the file, exit.
+ */
+ if (!opt_no_defaults && ((error= get_default_values())))
+ {
+ error= -1;
+ goto exit;
+ }
+
+ /*
+ Check to ensure required options are present and validate the operation.
+ Note: this method also validates the plugin specified by attempting to
+ read a configuration file named <plugin_name>.ini from the --plugin-dir
+ or --plugin-ini location if the --plugin-ini option presented.
+ */
+ strcpy(operation, "");
+ if ((error = check_options(argc, argv, operation)))
+ {
+ goto exit;
+ }
+
+ if (opt_verbose)
+ {
+ printf("# basedir = %s\n", opt_basedir);
+ printf("# plugin_dir = %s\n", opt_plugin_dir);
+ printf("# datadir = %s\n", opt_datadir);
+ printf("# plugin_ini = %s\n", opt_plugin_ini);
+ }
+
+exit:
+ return error;
+}
+
+
+/**
+ Check access
+
+ This method checks to ensure all of the directories (opt_basedir,
+ opt_plugin_dir, opt_datadir, and opt_plugin_ini) are accessible by
+ the user.
+
+ @retval int error = 1, success = 0
+*/
+
+static int check_access()
+{
+ int error= 0;
+
+ if ((error= my_access(opt_basedir, F_OK)))
+ {
+ fprintf(stderr, "ERROR: Cannot access basedir at '%s'.\n",
+ opt_basedir);
+ goto exit;
+ }
+ if ((error= my_access(opt_plugin_dir, F_OK)))
+ {
+ fprintf(stderr, "ERROR: Cannot access plugin_dir at '%s'.\n",
+ opt_plugin_dir);
+ goto exit;
+ }
+ if ((error= my_access(opt_datadir, F_OK)))
+ {
+ fprintf(stderr, "ERROR: Cannot access datadir at '%s'.\n",
+ opt_datadir);
+ goto exit;
+ }
+ if (opt_plugin_ini && (error= my_access(opt_plugin_ini, F_OK)))
+ {
+ fprintf(stderr, "ERROR: Cannot access plugin config file at '%s'.\n",
+ opt_plugin_ini);
+ goto exit;
+ }
+ if (opt_mysqld && (error= my_access(opt_mysqld, F_OK)))
+ {
+ fprintf(stderr, "ERROR: Cannot access mysqld path '%s'.\n",
+ opt_mysqld);
+ goto exit;
+ }
+ if (opt_my_print_defaults && (error= my_access(opt_my_print_defaults, F_OK)))
+ {
+ fprintf(stderr, "ERROR: Cannot access my-print-defaults path '%s'.\n",
+ opt_my_print_defaults);
+ goto exit;
+ }
+
+exit:
+ return error;
+}
+
+
+/**
+ Locate the tool and form tool path.
+
+ @param[in] tool_name Name of the tool to locate.
+ @param[out] tool_path If tool found, return complete path.
+
+ @retval int error = 1, success = 0
+*/
+
+static int find_tool(const char *tool_name, char *tool_path)
+{
+ int i= 0;
+
+ const char *paths[]= {
+ opt_mysqld, opt_basedir, opt_my_print_defaults, "/usr",
+ "/usr/local/mysql", "/usr/sbin", "/usr/share", "/extra", "/extra/debug",
+ "/extra/release", "/bin", "/usr/bin", "/mysql/bin"
+ };
+ for (i= 0; i < (int)array_elements(paths); i++)
+ {
+ if (paths[i] && (search_paths(paths[i], tool_name, tool_path)))
+ goto found;
+ }
+ fprintf(stderr, "WARNING: Cannot find %s.\n", tool_name);
+ return 1;
+found:
+ if (opt_verbose)
+ printf("# Found tool '%s' as '%s'.\n", tool_name, tool_path);
+ return 0;
+}
+
+
+/**
+ Find the plugin library.
+
+ This function attempts to use the @c plugin_dir option passed on the
+ command line to locate the plugin.
+
+ @param[out] tp_path The actual path to plugin with FN_SOEXT applied.
+
+ @retval int error = 1, success = 0
+*/
+
+static int find_plugin(char *tp_path)
+{
+ /* Check for existance of plugin */
+ fn_format(tp_path, plugin_data.so_name, opt_plugin_dir, "", MYF(0));
+ if (!file_exists(tp_path))
+ {
+ fprintf(stderr, "ERROR: The plugin library is missing or in a different"
+ " location.\n");
+ return 1;
+ }
+ else if (opt_verbose)
+ {
+ printf("# Found plugin '%s' as '%s'\n", plugin_data.name, tp_path);
+ }
+ return 0;
+}
+
+
+/**
+ Build the boostrap file.
+
+ Create a new file and populate it with SQL commands to ENABLE or DISABLE
+ the plugin via REPLACE and DELETE operations on the mysql.plugin table.
+
+ param[in] operation The type of operation (ENABLE or DISABLE)
+ param[out] bootstrap A FILE* pointer
+
+ @retval int error = 1, success = 0
+*/
+
+static int build_bootstrap_file(char *operation, char *bootstrap)
+{
+ int error= 0;
+ FILE *file= 0;
+
+ /*
+ Perform plugin operation : ENABLE or DISABLE
+
+ The following creates a temporary bootstrap file and populates it with
+ the appropriate SQL commands for the operation. For ENABLE, REPLACE
+ statements are created. For DISABLE, DELETE statements are created. The
+ values for these statements are derived from the plugin_data read from the
+ <plugin_name>.ini configuration file. Once the file is built, a call to
+ mysqld is made in read only, bootstrap modes to read the SQL statements
+ and execute them.
+
+ Note: Replace was used so that if a user loads a newer version of a
+ library with a different library name, the new library name is
+ used for symbols that match.
+ */
+ if ((error= make_tempfile(bootstrap, "sql")))
+ {
+ /* Fail if we cannot create a temporary file for the bootstrap commands. */
+ fprintf(stderr, "ERROR: Cannot create bootstrap file.\n");
+ goto exit;
+ }
+ if ((file= fopen(bootstrap, "w+")) == NULL)
+ {
+ fprintf(stderr, "ERROR: Cannot open bootstrap file for writing.\n");
+ error= 1;
+ goto exit;
+ }
+ if (strcasecmp(operation, "enable") == 0)
+ {
+ int i= 0;
+ fprintf(file, "REPLACE INTO mysql.plugin VALUES ");
+ for (i= 0; i < (int)array_elements(plugin_data.components); i++)
+ {
+ /* stop when we read the end of the symbol list - marked with NULL */
+ if (plugin_data.components[i] == NULL)
+ {
+ break;
+ }
+ if (i > 0)
+ {
+ fprintf(file, ", ");
+ }
+ fprintf(file, "('%s','%s')",
+ plugin_data.components[i], plugin_data.so_name);
+ }
+ fprintf(file, ";\n");
+ if (opt_verbose)
+ {
+ printf("# Enabling %s...\n", plugin_data.name);
+ }
+ }
+ else
+ {
+ fprintf(file,
+ "DELETE FROM mysql.plugin WHERE dl = '%s';", plugin_data.so_name);
+ if (opt_verbose)
+ {
+ printf("# Disabling %s...\n", plugin_data.name);
+ }
+ }
+
+exit:
+ fclose(file);
+ return error;
+}
+
+
+/**
+ Dump bootstrap file.
+
+ Read the contents of the bootstrap file and print it out.
+
+ @param[in] bootstrap_file Name of bootstrap file to read
+
+ @retval int error = 1, success = 0
+*/
+
+static int dump_bootstrap_file(char *bootstrap_file)
+{
+ char *ret= 0;
+ int error= 0;
+ char query_str[512];
+ FILE *file= 0;
+
+ if ((file= fopen(bootstrap_file, "r")) == NULL)
+ {
+ fprintf(stderr, "ERROR: Cannot open bootstrap file for reading.\n");
+ error= 1;
+ goto exit;
+ }
+ ret= fgets(query_str, 512, file);
+ if (ret == 0)
+ {
+ fprintf(stderr, "ERROR: Cannot read bootstrap file.\n");
+ error= 1;
+ goto exit;
+ }
+ printf("# Query: %s\n", query_str);
+
+exit:
+ if (file)
+ {
+ fclose(file);
+ }
+ return error;
+}
+
+
+/**
+ Bootstrap the server
+
+ Create a command line sequence to launch mysqld in bootstrap mode. This
+ will allow mysqld to launch a minimal server instance to read and
+ execute SQL commands from a file piped in (the boostrap file). We use
+ the --no-defaults option to skip reading values from the config file.
+
+ The bootstrap mode skips loading of plugins and many other subsystems.
+ This allows the mysql_plugin tool to insert the correct rows into the
+ mysql.plugin table (for ENABLE) or delete the rows (for DISABLE). Once
+ the server is launched in normal mode, the plugin will be loaded
+ (for ENABLE) or not loaded (for DISABLE). In this way, we avoid the
+ (sometimes) complicated LOAD PLUGIN commands.
+
+ @param[in] server_path Path to server executable
+ @param[in] bootstrap_file Name of bootstrap file to read
+
+ @retval int error = 1, success = 0
+*/
+
+static int bootstrap_server(char *server_path, char *bootstrap_file)
+{
+ char bootstrap_cmd[FN_REFLEN];
+ int error= 0;
+
+#ifdef __WIN__
+ char *format_str= 0;
+ const char *verbose_str= NULL;
+
+
+ if (opt_verbose)
+ verbose_str= "--console";
+ else
+ verbose_str= "";
+ if (has_spaces(opt_datadir) || has_spaces(opt_basedir) ||
+ has_spaces(bootstrap_file))
+ format_str= "\"%s %s --bootstrap --datadir=%s --basedir=%s < %s\"";
+ else
+ format_str= "%s %s --bootstrap --datadir=%s --basedir=%s < %s";
+
+ snprintf(bootstrap_cmd, sizeof(bootstrap_cmd), format_str,
+ add_quotes(convert_path(server_path)), verbose_str,
+ add_quotes(opt_datadir), add_quotes(opt_basedir),
+ add_quotes(bootstrap_file));
+#else
+ snprintf(bootstrap_cmd, sizeof(bootstrap_cmd),
+ "%s --no-defaults --bootstrap --datadir=%s --basedir=%s"
+ " < %s", server_path, opt_datadir, opt_basedir, bootstrap_file);
+#endif
+
+ /* Execute the command */
+ if (opt_verbose)
+ {
+ printf("# Command: %s\n", bootstrap_cmd);
+ }
+ error= run_command(bootstrap_cmd, "r");
+ if (error)
+ fprintf(stderr,
+ "ERROR: Unexpected result from bootstrap. Error code: %d.\n",
+ error);
+
+ return error;
+}
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index 2512f5269ab..8bbb8864afd 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -38,7 +38,8 @@
static char mysql_path[FN_REFLEN];
static char mysqlcheck_path[FN_REFLEN];
-static my_bool opt_force, opt_verbose, debug_info_flag, debug_check_flag;
+static my_bool opt_force, opt_verbose, debug_info_flag, debug_check_flag,
+ opt_systables_only;
static uint my_end_arg= 0;
static char *opt_user= (char*)"root";
@@ -46,6 +47,8 @@ static DYNAMIC_STRING ds_args;
static DYNAMIC_STRING conn_args;
static char *opt_password= 0;
+static char *opt_plugin_dir= 0, *opt_default_auth= 0;
+
static my_bool tty_password= 0;
static char opt_tmpdir[FN_REFLEN] = "";
@@ -60,8 +63,6 @@ static my_bool not_used; /* Can't use GET_BOOL without a value pointer */
static my_bool opt_write_binlog;
-#include <help_start.h>
-
static struct my_option my_long_options[]=
{
{"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
@@ -91,6 +92,10 @@ static struct my_option my_long_options[]=
{"default-character-set", OPT_DEFAULT_CHARSET,
"Set the default character set.", 0,
0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"default_auth", OPT_DEFAULT_AUTH,
+ "Default authentication client-side plugin to use.",
+ &opt_default_auth, &opt_default_auth, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"force", 'f', "Force execution of mysqlcheck even if mysql_upgrade "
"has already been executed for the current version of MySQL.",
&opt_force, &opt_force, 0,
@@ -105,6 +110,9 @@ static struct my_option my_long_options[]=
{"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
+ &opt_plugin_dir, &opt_plugin_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"port", 'P', "Port number to use for connection or 0 for default to, in "
"order of preference, my.cnf, $MYSQL_TCP_PORT, "
#if MYSQL_PORT_DEFAULT == 0
@@ -125,6 +133,10 @@ static struct my_option my_long_options[]=
#include <sslopt-longopts.h>
{"tmpdir", 't', "Directory for temporary files.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"upgrade-system-tables", 's', "Only upgrade the system tables "
+ "do not try to upgrade the data.",
+ &opt_systables_only, &opt_systables_only, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"user", 'u', "User for login if not current user.", &opt_user,
&opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"verbose", 'v', "Display more output about the process.",
@@ -138,8 +150,6 @@ static struct my_option my_long_options[]=
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-#include <help_end.h>
-
static void free_used_memory(void)
{
@@ -212,6 +222,9 @@ static void add_one_option(DYNAMIC_STRING* ds,
case GET_STR:
arg= argument;
break;
+ case GET_BOOL:
+ arg= (*(my_bool *)opt->value) ? "1" : "0";
+ break;
default:
die("internal error at %s: %d",__FILE__, __LINE__);
}
@@ -230,9 +243,9 @@ get_one_option(int optid, const struct my_option *opt,
switch (optid) {
case '?':
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000"));
printf("%s Ver %s Distrib %s, for %s (%s)\n",
my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
+ puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000"));
puts("MySQL utility for upgrading databases to new MySQL versions.\n");
my_print_help(my_long_options);
exit(0);
@@ -272,6 +285,8 @@ get_one_option(int optid, const struct my_option *opt,
case 'v': /* --verbose */
case 'f': /* --force */
+ case 's': /* --upgrade-system-tables */
+ case OPT_WRITE_BINLOG: /* --write-binlog */
add_option= FALSE;
break;
@@ -281,6 +296,8 @@ get_one_option(int optid, const struct my_option *opt,
case 'S': /* --socket */
case OPT_MYSQL_PROTOCOL: /* --protocol */
case OPT_SHARED_MEMORY_BASE_NAME: /* --shared-memory-base-name */
+ case OPT_PLUGIN_DIR: /* --plugin-dir */
+ case OPT_DEFAULT_AUTH: /* --default-auth */
add_one_option(&conn_args, opt, argument);
break;
}
@@ -812,9 +829,6 @@ int main(int argc, char **argv)
char self_name[FN_REFLEN];
MY_INIT(argv[0]);
-#ifdef __NETWARE__
- setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
-#endif
#if __WIN__
if (GetModuleFileName(NULL, self_name, FN_REFLEN) == 0)
@@ -827,7 +841,8 @@ int main(int argc, char **argv)
init_dynamic_string(&conn_args, "", 512, 256))
die("Out of memory");
- load_defaults("my", load_default_groups, &argc, &argv);
+ if (load_defaults("my", load_default_groups, &argc, &argv))
+ die(NULL);
defaults_argv= argv; /* Must be freed by 'free_defaults' */
if (handle_options(&argc, &argv, my_long_options, get_one_option))
@@ -851,8 +866,15 @@ int main(int argc, char **argv)
/* Find mysql */
find_tool(mysql_path, IF_WIN("mysql.exe", "mysql"), self_name);
- /* Find mysqlcheck */
- find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck"), self_name);
+ if (!opt_systables_only)
+ {
+ /* Find mysqlcheck */
+ find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck"), self_name);
+ }
+ else
+ {
+ printf("The --upgrade-system-tables option was used, databases won't be touched.\n");
+ }
/*
Read the mysql_upgrade_info file to check if mysql_upgrade
@@ -869,8 +891,8 @@ int main(int argc, char **argv)
/*
Run "mysqlcheck" and "mysql_fix_privilege_tables.sql"
*/
- if (run_mysqlcheck_fixnames() ||
- run_mysqlcheck_upgrade() ||
+ if ((!opt_systables_only &&
+ (run_mysqlcheck_fixnames() || run_mysqlcheck_upgrade())) ||
run_sql_fix_privilege_tables())
{
/*
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index d5d6ad9ff6a..2a1d61395e2 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -12,16 +12,13 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* maintaince of mysql databases */
#include "client_priv.h"
#include <signal.h>
-#ifdef THREAD
#include <my_pthread.h> /* because of signal() */
-#endif
#include <sys/stat.h>
#include <mysql.h>
#include <sql_common.h>
@@ -33,7 +30,7 @@
#define MAX_TRUNC_LENGTH 3
char *host= NULL, *user= 0, *opt_password= 0,
- *default_charset= NULL;
+ *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME;
char truncated_var_names[MAX_MYSQL_VAR][MAX_TRUNC_LENGTH];
char ex_var_names[MAX_MYSQL_VAR][FN_REFLEN];
ulonglong last_values[MAX_MYSQL_VAR];
@@ -46,6 +43,9 @@ static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations;
static uint opt_count_iterations= 0, my_end_arg;
static ulong opt_connect_timeout, opt_shutdown_timeout;
static char * unix_port=0;
+static char *opt_plugin_dir= 0, *opt_default_auth= 0;
+static uint opt_enable_cleartext_plugin= 0;
+static my_bool using_opt_enable_cleartext_plugin= 0;
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
@@ -119,10 +119,6 @@ static TYPELIB command_typelib=
static struct my_option my_long_options[] =
{
-#ifdef __NETWARE__
- {"autoclose", OPT_AUTO_CLOSE, "Automatically close the screen on exit for Netware.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-#endif
{"count", 'c',
"Number of iterations to make. This works with -i (--sleep) only.",
&nr_iterations, &nr_iterations, 0, GET_UINT,
@@ -138,7 +134,8 @@ static struct my_option my_long_options[] =
&debug_info_flag, &debug_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.",
+ "Don't ask for confirmation on drop database; with multiple commands, "
+ "continue even if an error occurs.",
&option_force, &option_force, 0, GET_BOOL, NO_ARG, 0, 0,
0, 0, 0, 0},
{"compress", 'C', "Use compression in server/client protocol.",
@@ -169,8 +166,7 @@ static struct my_option my_long_options[] =
"/etc/services, "
#endif
"built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
- &tcp_port,
- &tcp_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ &tcp_port, &tcp_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"protocol", OPT_MYSQL_PROTOCOL, "The protocol to use for connection (tcp, socket, pipe, memory).",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"relative", 'r',
@@ -178,10 +174,6 @@ static struct my_option my_long_options[] =
"Currently only works with extended-status.",
&opt_relative, &opt_relative, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
- {"set-variable", 'O',
- "Change the value of a variable. Please note that this option is "
- "deprecated; you can set variables directly with --variable-name=value.",
- 0, 0, 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.", &shared_memory_base_name, &shared_memory_base_name,
@@ -216,6 +208,17 @@ static struct my_option my_long_options[] =
{"shutdown_timeout", OPT_SHUTDOWN_TIMEOUT, "", &opt_shutdown_timeout,
&opt_shutdown_timeout, 0, GET_ULONG, REQUIRED_ARG,
SHUTDOWN_DEF_TIMEOUT, 0, 3600*12, 0, 1, 0},
+ {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
+ &opt_plugin_dir, &opt_plugin_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"default_auth", OPT_DEFAULT_AUTH,
+ "Default authentication client-side plugin to use.",
+ &opt_default_auth, &opt_default_auth, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"enable_cleartext_plugin", OPT_ENABLE_CLEARTEXT_PLUGIN,
+ "Enable/disable the clear text authentication plugin.",
+ &opt_enable_cleartext_plugin, &opt_enable_cleartext_plugin,
+ 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -229,11 +232,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
int error = 0;
switch(optid) {
-#ifdef __NETWARE__
- case OPT_AUTO_CLOSE:
- setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
- break;
-#endif
case 'c':
opt_count_iterations= 1;
break;
@@ -243,7 +241,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
if (argument)
{
char *start=argument;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_password);
opt_password=my_strdup(argument,MYF(MY_FAE));
while (*argument) *argument++= 'x'; /* Destroy argument */
if (*start)
@@ -287,13 +285,13 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
charsets_dir = argument;
#endif
break;
- case 'O':
- WARN_DEPRECATED(VER_CELOSIA, "--set-variable", "--variable-name=value");
- break;
case OPT_MYSQL_PROTOCOL:
opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
opt->name);
break;
+ case OPT_ENABLE_CLEARTEXT_PLUGIN:
+ using_opt_enable_cleartext_plugin= TRUE;
+ break;
}
if (error)
{
@@ -312,7 +310,8 @@ int main(int argc,char *argv[])
MY_INIT(argv[0]);
mysql_init(&mysql);
- load_defaults("my",load_default_groups,&argc,&argv);
+ if (load_defaults("my",load_default_groups,&argc,&argv))
+ exit(1);
save_argv = argv; /* Save for free_defaults */
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
{
@@ -333,8 +332,8 @@ int main(int argc,char *argv[])
if (tty_password)
opt_password = get_tty_password(NullS);
- VOID(signal(SIGINT,endprog)); /* Here if abort */
- VOID(signal(SIGTERM,endprog)); /* Here if abort */
+ (void) signal(SIGINT,endprog); /* Here if abort */
+ (void) signal(SIGTERM,endprog); /* Here if abort */
if (opt_compress)
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
@@ -356,10 +355,19 @@ int main(int argc,char *argv[])
if (shared_memory_base_name)
mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
- if (default_charset)
- mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
+ mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
error_flags= (myf)(opt_nobeep ? 0 : ME_BELL);
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(&mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (opt_default_auth && *opt_default_auth)
+ mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
+
+ if (using_opt_enable_cleartext_plugin)
+ mysql_options(&mysql, MYSQL_ENABLE_CLEARTEXT_PLUGIN,
+ (char*) &opt_enable_cleartext_plugin);
+
if (sql_connect(&mysql, option_wait))
{
/*
@@ -375,7 +383,8 @@ int main(int argc,char *argv[])
/* Return 0 if all commands are PING */
for (; argc > 0; argv++, argc--)
{
- if (find_type(argv[0], &command_typelib, 2) != ADMIN_PING)
+ if (find_type(argv[0], &command_typelib, FIND_TYPE_BASIC) !=
+ ADMIN_PING)
{
error= 1;
break;
@@ -461,10 +470,10 @@ int main(int argc,char *argv[])
} /* got connection */
mysql_close(&mysql);
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
- my_free(user,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_password);
+ my_free(user);
#ifdef HAVE_SMEM
- my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(shared_memory_base_name);
#endif
free_defaults(save_argv);
my_end(my_end_arg);
@@ -598,7 +607,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
for (; argc > 0 ; argv++,argc--)
{
- switch (find_type(argv[0],&command_typelib,2)) {
+ switch (find_type(argv[0],&command_typelib, FIND_TYPE_BASIC)) {
case ADMIN_CREATE:
{
char buff[FN_REFLEN+20];
@@ -911,23 +920,38 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
{
char buff[128],crypted_pw[64];
time_t start_time;
+ char *typed_password= NULL, *verified= NULL;
/* Do initialization the same way as we do in mysqld */
start_time=time((time_t*) 0);
randominit(&rand_st,(ulong) start_time,(ulong) start_time/2);
- if (argc < 2)
+ if (argc < 1)
{
my_printf_error(0, "Too few arguments to change password", error_flags);
return 1;
}
- if (argv[1][0])
+ else if (argc == 1)
+ {
+ /* prompt for password */
+ typed_password= get_tty_password("New password: ");
+ verified= get_tty_password("Confirm new password: ");
+ if (strcmp(typed_password, verified) != 0)
+ {
+ my_printf_error(0,"Passwords don't match",MYF(ME_BELL));
+ return -1;
+ }
+ }
+ else
+ typed_password= argv[1];
+
+ if (typed_password[0])
{
- char *pw= argv[1];
- bool old= (find_type(argv[0], &command_typelib, 2) ==
+ bool old= (find_type(argv[0], &command_typelib, FIND_TYPE_BASIC) ==
ADMIN_OLD_PASSWORD);
#ifdef __WIN__
- uint pw_len= (uint) strlen(pw);
- if (pw_len > 1 && pw[0] == '\'' && pw[pw_len-1] == '\'')
+ size_t pw_len= strlen(typed_password);
+ if (pw_len > 1 && typed_password[0] == '\'' &&
+ typed_password[pw_len-1] == '\'')
printf("Warning: single quotes were not trimmed from the password by"
" your command\nline client, as you might have expected.\n");
#endif
@@ -965,9 +989,9 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
}
if (old)
- make_scrambled_password_323(crypted_pw, pw);
+ make_scrambled_password_323(crypted_pw, typed_password);
else
- make_scrambled_password(crypted_pw, pw);
+ make_scrambled_password(crypted_pw, typed_password);
}
else
crypted_pw[0]=0; /* No password */
@@ -1002,6 +1026,12 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
return -1;
}
}
+ /* free up memory from prompted password */
+ if (typed_password != argv[1])
+ {
+ my_free(typed_password);
+ my_free(verified);
+ }
argc--; argv++;
break;
}
@@ -1059,13 +1089,11 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
return 0;
}
-#include <help_start.h>
static void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s on %s\n",my_progname,ADMIN_VERSION,
MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
- NETWARE_SET_SCREEN_MODE(1);
}
@@ -1092,8 +1120,8 @@ static void usage(void)
kill id,id,... Kill mysql threads");
#if MYSQL_VERSION_ID >= 32200
puts("\
- password new-password Change old password to new-password, MySQL 4.1 hashing.\n\
- old-password new-password Change old password to new-password in old format.\n");
+ password [new-password] Change old password to new-password in current format\n\
+ old-password [new-password] Change old password to new-password in old format");
#endif
puts("\
ping Check if mysqld is alive\n\
@@ -1108,7 +1136,6 @@ static void usage(void)
version Get version info from server");
}
-#include <help_end.h>
static int drop_db(MYSQL *mysql, const char *db)
{
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index c32f92ae149..a58aa65207d 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -33,7 +33,7 @@
#include "client_priv.h"
#include <my_time.h>
/* That one is necessary for defines of OPTION_NO_FOREIGN_KEY_CHECKS etc */
-#include "mysql_priv.h"
+#include "sql_priv.h"
#include "log_event.h"
#include "sql_common.h"
#include "my_dir.h"
@@ -45,7 +45,6 @@
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
-
char server_version[SERVER_VERSION_LENGTH];
ulong server_id = 0;
@@ -73,20 +72,22 @@ TYPELIB base64_output_mode_typelib=
{ array_elements(base64_output_mode_names) - 1, "",
base64_output_mode_names, NULL };
static enum_base64_output_mode opt_base64_output_mode= BASE64_OUTPUT_UNSPEC;
-static const char *opt_base64_output_mode_str= NullS;
-static const char* database= 0;
+static char *opt_base64_output_mode_str= NullS;
+static char* database= 0;
static my_bool force_opt= 0, short_form= 0, remote_opt= 0;
static my_bool debug_info_flag, debug_check_flag;
static my_bool force_if_open_opt= 1;
static ulonglong offset = 0;
-static const char* host = 0;
+static char* host = 0;
static int port= 0;
static uint my_end_arg;
static const char* sock= 0;
+static char *opt_plugin_dir= 0, *opt_default_auth= 0;
+
#ifdef HAVE_SMEM
static char *shared_memory_base_name= 0;
#endif
-static const char* user = 0;
+static char* user = 0;
static char* pass = 0;
static char *charset= 0;
@@ -101,7 +102,7 @@ static my_time_t start_datetime= 0, stop_datetime= MY_TIME_T_MAX;
static ulonglong rec_count= 0;
static short binlog_flags = 0;
static MYSQL* mysql = NULL;
-static const char* dirname_for_local_load= 0;
+static char* dirname_for_local_load= 0;
/**
Pointer to the Format_description_log_event of the currently active binlog.
@@ -196,7 +197,7 @@ public:
int init()
{
return init_dynamic_array(&file_names, sizeof(File_name_record),
- 100,100 CALLER_INFO);
+ 100, 100);
}
void init_by_dir_name(const char *dir)
@@ -218,7 +219,7 @@ public:
{
if (ptr->fname)
{
- my_free(ptr->fname, MYF(MY_WME));
+ my_free(ptr->fname);
delete ptr->event;
bzero((char *)ptr, sizeof(File_name_record));
}
@@ -447,6 +448,7 @@ Exit_status Load_log_processor::process_first_event(const char *bname,
{
error("Could not construct local filename %s%s.",
target_dir_name,bname);
+ my_free(fname);
delete ce;
DBUG_RETURN(ERROR_STOP);
}
@@ -454,9 +456,15 @@ Exit_status Load_log_processor::process_first_event(const char *bname,
rec.fname= fname;
rec.event= ce;
+ /*
+ fname is freed in process_event()
+ after Execute_load_query_log_event or Execute_load_log_event
+ will have been processed, otherwise in Load_log_processor::destroy()
+ */
if (set_dynamic(&file_names, (uchar*)&rec, file_id))
{
error("Out of memory.");
+ my_free(fname);
delete ce;
DBUG_RETURN(ERROR_STOP);
}
@@ -838,7 +846,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
*/
convert_path_to_forward_slashes((char*) ce->fname);
ce->print(result_file, print_event_info, TRUE);
- my_free((char*)ce->fname,MYF(MY_WME));
+ my_free((void*)ce->fname);
delete ce;
if (head->error == -1)
goto err;
@@ -857,10 +865,16 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
if (head->error == -1)
goto err;
if (!remote_opt)
+ {
ev->free_temp_buf(); // free memory allocated in dump_local_log_entries
+ }
else
- // disassociate but not free dump_remote_log_entries time memory
+ {
+ /*
+ disassociate but not free dump_remote_log_entries time memory
+ */
ev->temp_buf= 0;
+ }
/*
We don't want this event to be deleted now, so let's hide it (I
(Guilhem) should later see if this triggers a non-serious Valgrind
@@ -899,7 +913,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
if (head->error == -1)
{
if (fname)
- my_free(fname, MYF(MY_WME));
+ my_free(fname);
goto err;
}
}
@@ -909,7 +923,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
}
if (fname)
- my_free(fname, MYF(MY_WME));
+ my_free(fname);
break;
}
case TABLE_MAP_EVENT:
@@ -1027,10 +1041,6 @@ 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, "Automatically 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_MODE,
/* 'unspec' is not mentioned because it is just a placeholder. */
"Determine when the output statements should be base64-encoded BINLOG "
@@ -1038,10 +1048,11 @@ static struct my_option my_long_options[] =
"row-based events; 'decode-rows' decodes row events into commented SQL "
"statements if the --verbose option is also given; 'auto' prints base64 "
"only when necessary (i.e., for row-based events and format description "
- "events); 'always' prints base64 whenever possible. 'always' is for "
- "debugging only and should not be used in a production system. If this "
- "argument is not given, the default is 'auto'; if it is given with no "
- "argument, 'always' is used.",
+ "events); 'always' prints base64 whenever possible. 'always' is "
+ "deprecated, will be removed in a future version, and should not be used "
+ "in a production system. --base64-output with no 'name' argument is "
+ "equivalent to --base64-output=always and is also deprecated. If no "
+ "--base64-output[=name] option is given at all, the default is 'auto'.",
&opt_base64_output_mode_str, &opt_base64_output_mode_str,
0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
/*
@@ -1066,6 +1077,10 @@ static struct my_option my_long_options[] =
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
&debug_info_flag, &debug_info_flag,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"default_auth", OPT_DEFAULT_AUTH,
+ "Default authentication client-side plugin to use.",
+ &opt_default_auth, &opt_default_auth, 0,
+ GET_STR, REQUIRED_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 "
@@ -1091,6 +1106,9 @@ static struct my_option my_long_options[] =
0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"password", 'p', "Password to connect to remote server.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
+ &opt_plugin_dir, &opt_plugin_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"port", 'P', "Port number to use for connection or 0 for default to, in "
"order of preference, my.cnf, $MYSQL_TCP_PORT, "
#if MYSQL_PORT_DEFAULT == 0
@@ -1099,11 +1117,6 @@ static struct my_option my_long_options[] =
"built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
&port, &port, 0, GET_INT, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
- {"position", OPT_POSITION, "Deprecated. Use --start-position instead.",
- &start_position, &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},
{"protocol", OPT_MYSQL_PROTOCOL,
"The protocol to use for connection (tcp, socket, pipe, memory).",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -1132,7 +1145,7 @@ static struct my_option my_long_options[] =
&short_form, &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
{"socket", 'S', "The socket file to use for connection.",
- &sock, &sock, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
+ &sock, &sock, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
0, 0},
{"start-datetime", OPT_START_DATETIME,
"Start reading the binlog at first event having a datetime equal or "
@@ -1252,23 +1265,21 @@ static void warning(const char *format,...)
*/
static void cleanup()
{
- my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
- my_free((char*) database, MYF(MY_ALLOW_ZERO_PTR));
- my_free((char*) host, MYF(MY_ALLOW_ZERO_PTR));
- my_free((char*) user, MYF(MY_ALLOW_ZERO_PTR));
- my_free((char*) dirname_for_local_load, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(pass);
+ my_free(database);
+ my_free(host);
+ my_free(user);
+ my_free(dirname_for_local_load);
delete glob_description_event;
if (mysql)
mysql_close(mysql);
}
-#include <help_start.h>
static void print_version()
{
printf("%s Ver 3.3 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE);
- NETWARE_SET_SCREEN_MODE(1);
}
@@ -1307,7 +1318,6 @@ static my_time_t convert_str_to_timestamp(const char* str)
my_system_gmt_sec(&l_time, &dummy_my_timezone, &dummy_in_dst_time_gap);
}
-#include <help_end.h>
extern "C" my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
@@ -1315,11 +1325,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
{
bool tty_password=0;
switch (optid) {
-#ifdef __NETWARE__
- case OPT_AUTO_CLOSE:
- setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
- break;
-#endif
#ifndef DBUG_OFF
case '#':
DBUG_PUSH(argument ? argument : default_dbug_option);
@@ -1333,7 +1338,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
argument= (char*) ""; // Don't require password
if (argument)
{
- my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(pass);
char *start=argument;
pass= my_strdup(argument,MYF(MY_FAE));
while (*argument) *argument++= 'x'; /* Destroy argument */
@@ -1350,9 +1355,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case 'R':
remote_opt= 1;
break;
- case OPT_POSITION:
- WARN_DEPRECATED(VER_CELOSIA, "--position", "--start-position");
- break;
case OPT_MYSQL_PROTOCOL:
opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
opt->name);
@@ -1424,6 +1426,12 @@ static Exit_status safe_connect()
return ERROR_STOP;
}
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (opt_default_auth && *opt_default_auth)
+ mysql_options(mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
+
if (opt_protocol)
mysql_options(mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol);
#ifdef HAVE_SMEM
@@ -1974,7 +1982,7 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
return ERROR_STOP;
}
#endif
- if (init_io_cache(file, fileno(stdin), 0, READ_CACHE, (my_off_t) 0,
+ if (init_io_cache(file, my_fileno(stdin), 0, READ_CACHE, (my_off_t) 0,
0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE)))
{
error("Failed to init IO cache.");
@@ -2078,11 +2086,19 @@ int main(int argc, char** argv)
{
usage();
free_defaults(defaults_argv);
+ my_end(my_end_arg);
exit(1);
}
if (opt_base64_output_mode == BASE64_OUTPUT_UNSPEC)
opt_base64_output_mode= BASE64_OUTPUT_AUTO;
+ if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS)
+ warning("The --base64-output=always flag and the --base64-output flag "
+ "(with '=MODE' omitted), are deprecated. "
+ "The output generated when these flags are used cannot be "
+ "parsed by mysql 5.6.0 and later. "
+ "The flags will be removed in a future version. "
+ "Please use --base64-output=auto instead.");
my_set_max_open_files(open_files_limit);
@@ -2178,4 +2194,4 @@ int main(int argc, char** argv)
#include "my_decimal.cc"
#include "log_event.cc"
#include "log_event_old.cc"
-
+#include "rpl_utility.cc"
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index ec9ee50868b..8a9711fffae 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -42,14 +42,15 @@ static int my_end_arg;
static char * opt_mysql_unix_port = 0;
static char *opt_password = 0, *current_user = 0,
*default_charset= 0, *current_host= 0;
+static char *opt_plugin_dir= 0, *opt_default_auth= 0;
static int first_error = 0;
-DYNAMIC_ARRAY tables4repair;
+DYNAMIC_ARRAY tables4repair, tables4rebuild;
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol=0;
-enum operations { DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE };
+enum operations { DO_CHECK=1, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE };
static struct my_option my_long_options[] =
{
@@ -63,10 +64,6 @@ static struct my_option my_long_options[] =
"Instead of issuing one query for each table, use one query per database, naming all tables in the database in a comma-separated list.",
&opt_all_in_1, &opt_all_in_1, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
-#ifdef __NETWARE__
- {"autoclose", OPT_AUTO_CLOSE, "Automatically close the screen on exit for Netware.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-#endif
{"auto-repair", OPT_AUTO_REPAIR,
"If a checked table is corrupted, automatically fix it. Repairing will be done after all tables have been checked, if corrupted ones were found.",
&opt_auto_repair, &opt_auto_repair, 0, GET_BOOL, NO_ARG, 0,
@@ -105,6 +102,10 @@ static struct my_option my_long_options[] =
{"default-character-set", OPT_DEFAULT_CHARSET,
"Set the default character set.", &default_charset,
&default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"default_auth", OPT_DEFAULT_AUTH,
+ "Default authentication client-side plugin to use.",
+ &opt_default_auth, &opt_default_auth, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"fast",'F', "Check only tables that haven't been closed properly.",
&opt_fast, &opt_fast, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
0},
@@ -129,7 +130,8 @@ static struct my_option my_long_options[] =
"Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"write-binlog", OPT_WRITE_BINLOG,
- "Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Enabled by default; use --skip-write-binlog when commands should not be sent to replication slaves.",
+ "Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Use --skip-write-binlog "
+ "when commands should not be sent to replication slaves.",
&opt_write_binlog, &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,
@@ -141,14 +143,16 @@ static struct my_option my_long_options[] =
{"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
+ &opt_plugin_dir, &opt_plugin_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"port", 'P', "Port number to use for connection or 0 for default to, in "
"order of preference, my.cnf, $MYSQL_TCP_PORT, "
#if MYSQL_PORT_DEFAULT == 0
"/etc/services, "
#endif
"built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
- &opt_mysql_port,
- &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
+ &opt_mysql_port, &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
0},
{"protocol", OPT_MYSQL_PROTOCOL, "The protocol to use for connection (tcp, socket, pipe, memory).",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -209,13 +213,11 @@ static uint fixed_name_length(const char *name);
static char *fix_table_name(char *dest, char *src);
int what_to_do = 0;
-#include <help_start.h>
static void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, CHECK_VERSION,
MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
- NETWARE_SET_SCREEN_MODE(1);
} /* print_version */
@@ -244,18 +246,14 @@ static void usage(void)
my_print_variables(my_long_options);
} /* usage */
-#include <help_end.h>
static my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument)
{
+ int orig_what_to_do= what_to_do;
+
switch(optid) {
-#ifdef __NETWARE__
- case OPT_AUTO_CLOSE:
- setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
- break;
-#endif
case 'a':
what_to_do = DO_ANALYZE;
break;
@@ -290,7 +288,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
if (argument)
{
char *start = argument;
- my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_password);
opt_password = my_strdup(argument, MYF(MY_FAE));
while (*argument) *argument++= 'x'; /* Destroy argument */
if (*start)
@@ -329,6 +327,13 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
opt->name);
break;
}
+
+ if (orig_what_to_do && (what_to_do != orig_what_to_do))
+ {
+ fprintf(stderr, "Error: %s doesn't support multiple contradicting commands.\n",
+ my_progname);
+ return 1;
+ }
return 0;
}
@@ -343,9 +348,8 @@ static int get_options(int *argc, char ***argv)
exit(0);
}
- load_defaults("my", load_default_groups, argc, argv);
-
- if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+ if ((ho_error= load_defaults("my", load_default_groups, argc, argv)) ||
+ (ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
exit(ho_error);
if (!what_to_do)
@@ -368,12 +372,15 @@ static int get_options(int *argc, char ***argv)
If there's no --default-character-set option given with
--fix-table-name or --fix-db-name set the default character set to "utf8".
*/
- if (!default_charset && (opt_fix_db_names || opt_fix_table_names))
+ if (!default_charset)
{
- default_charset= (char*) "utf8";
+ if (opt_fix_db_names || opt_fix_table_names)
+ default_charset= (char*) "utf8";
+ else
+ default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME;
}
- if (default_charset && !get_charset_by_csname(default_charset, MY_CS_PRIMARY,
- MYF(MY_WME)))
+ if (strcmp(default_charset, MYSQL_AUTODETECT_CHARSET_NAME) &&
+ !get_charset_by_csname(default_charset, MY_CS_PRIMARY, MYF(MY_WME)))
{
printf("Unsupported character set: %s\n", default_charset);
return 1;
@@ -467,7 +474,7 @@ static int process_selected_tables(char *db, char **table_names, int tables)
}
*--end = 0;
handle_request_for_tables(table_names_comma_sep + 1, (uint) (tot_length - 1));
- my_free(table_names_comma_sep, MYF(0));
+ my_free(table_names_comma_sep);
}
else
for (; tables > 0; tables--, table_names++)
@@ -566,7 +573,7 @@ static int process_all_tables_in_db(char *database)
*--end = 0;
if (tot_length)
handle_request_for_tables(tables + 1, tot_length - 1);
- my_free(tables, MYF(0));
+ my_free(tables);
}
else
{
@@ -621,6 +628,27 @@ static int fix_database_storage_name(const char *name)
return rc;
}
+static int rebuild_table(char *name)
+{
+ char *query, *ptr;
+ int rc= 0;
+ query= (char*)my_malloc(sizeof(char) * (12 + fixed_name_length(name) + 6 + 1),
+ MYF(MY_WME));
+ if (!query)
+ return 1;
+ ptr= strmov(query, "ALTER TABLE ");
+ ptr= fix_table_name(ptr, name);
+ ptr= strxmov(ptr, " FORCE", NullS);
+ if (mysql_real_query(sock, query, (uint)(ptr - query)))
+ {
+ fprintf(stderr, "Failed to %s\n", query);
+ fprintf(stderr, "Error: %s\n", mysql_error(sock));
+ rc= 1;
+ }
+ my_free(query);
+ return rc;
+}
+
static int process_one_db(char *database)
{
if (what_to_do == DO_UPGRADE)
@@ -640,8 +668,11 @@ static int process_one_db(char *database)
static int use_db(char *database)
{
- if (mysql_get_server_version(sock) >= 50003 &&
- !my_strcasecmp(&my_charset_latin1, database, "information_schema"))
+ if (mysql_get_server_version(sock) >= FIRST_INFORMATION_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, database, INFORMATION_SCHEMA_DB_NAME))
+ return 1;
+ if (mysql_get_server_version(sock) >= FIRST_PERFORMANCE_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, database, PERFORMANCE_SCHEMA_DB_NAME))
return 1;
if (mysql_select_db(sock, database))
{
@@ -720,7 +751,7 @@ static int handle_request_for_tables(char *tables, uint length)
return 1;
}
print_result();
- my_free(query, MYF(0));
+ my_free(query);
return 0;
}
@@ -731,7 +762,7 @@ static void print_result()
MYSQL_ROW row;
char prev[NAME_LEN*2+2];
uint i;
- my_bool found_error=0;
+ my_bool found_error=0, table_rebuild=0;
res = mysql_use_result(sock);
@@ -750,8 +781,14 @@ static void print_result()
*/
if (found_error && opt_auto_repair && what_to_do != DO_REPAIR &&
strcmp(row[3],"OK"))
- insert_dynamic(&tables4repair, (uchar*) prev);
+ {
+ if (table_rebuild)
+ insert_dynamic(&tables4rebuild, (uchar*) prev);
+ else
+ insert_dynamic(&tables4repair, (uchar*) prev);
+ }
found_error=0;
+ table_rebuild=0;
if (opt_silent)
continue;
}
@@ -761,7 +798,11 @@ static void print_result()
{
printf("%s\n%-9s: %s", row[0], row[2], row[3]);
if (strcmp(row[2],"note"))
+ {
found_error=1;
+ if (opt_auto_repair && strstr(row[3], "ALTER TABLE") != NULL)
+ table_rebuild=1;
+ }
}
else
printf("%-9s: %s", row[2], row[3]);
@@ -770,7 +811,12 @@ static void print_result()
}
/* add the last table to be repaired to the list */
if (found_error && opt_auto_repair && what_to_do != DO_REPAIR)
- insert_dynamic(&tables4repair, (uchar*) prev);
+ {
+ if (table_rebuild)
+ insert_dynamic(&tables4rebuild, (uchar*) prev);
+ else
+ insert_dynamic(&tables4repair, (uchar*) prev);
+ }
mysql_free_result(res);
}
@@ -796,8 +842,14 @@ static int dbConnect(char *host, char *user, char *passwd)
if (shared_memory_base_name)
mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
- if (default_charset)
- mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset);
+
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(&mysql_connection, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (opt_default_auth && *opt_default_auth)
+ mysql_options(&mysql_connection, MYSQL_DEFAULT_AUTH, opt_default_auth);
+
+ mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset);
if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd,
NULL, opt_mysql_port, opt_mysql_unix_port, 0)))
{
@@ -862,7 +914,8 @@ int main(int argc, char **argv)
}
if (opt_auto_repair &&
- my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16,64))
+ (my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16,64) ||
+ my_init_dynamic_array(&tables4rebuild, sizeof(char)*(NAME_LEN*2+2),16,64)))
{
first_error = 1;
goto end;
@@ -880,7 +933,7 @@ int main(int argc, char **argv)
{
uint i;
- if (!opt_silent && tables4repair.elements)
+ if (!opt_silent && (tables4repair.elements || tables4rebuild.elements))
puts("\nRepairing tables");
what_to_do = DO_REPAIR;
for (i = 0; i < tables4repair.elements ; i++)
@@ -888,14 +941,19 @@ int main(int argc, char **argv)
char *name= (char*) dynamic_array_ptr(&tables4repair, i);
handle_request_for_tables(name, fixed_name_length(name));
}
+ for (i = 0; i < tables4rebuild.elements ; i++)
+ rebuild_table((char*) dynamic_array_ptr(&tables4rebuild, i));
}
end:
dbDisconnect(current_host);
if (opt_auto_repair)
+ {
delete_dynamic(&tables4repair);
- my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
+ delete_dynamic(&tables4rebuild);
+ }
+ my_free(opt_password);
#ifdef HAVE_SMEM
- my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(shared_memory_base_name);
#endif
my_end(my_end_arg);
return(first_error!=0);
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 3fda1fafc24..4fcf309b22b 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* mysqldump.c - Dump a tables contents and format to an ASCII file
@@ -52,7 +52,6 @@
#include "mysql.h"
#include "mysql_version.h"
#include "mysqld_error.h"
-#include "../sql/ha_ndbcluster_tables.h"
#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
@@ -114,6 +113,8 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0,
opt_complete_insert= 0, opt_drop_database= 0,
opt_replace_into= 0,
opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1,
+ opt_slave_apply= 0,
+ opt_include_master_host_port= 0,
opt_events= 0, opt_comments_used= 0,
opt_alltspcs=0, opt_notspcs= 0;
static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0;
@@ -134,7 +135,10 @@ static my_bool server_supports_switching_charsets= TRUE;
static ulong opt_compatible_mode= 0;
#define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
#define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2
+#define MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL 1
+#define MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL 2
static uint opt_mysql_port= 0, opt_master_data;
+static uint opt_slave_data;
static uint my_end_arg;
static char * opt_mysql_unix_port=0;
static int first_error=0;
@@ -147,6 +151,7 @@ FILE *stderror_file=0;
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol= 0;
+static char *opt_plugin_dir= 0, *opt_default_auth= 0;
/*
Dynamic_string wrapper functions. In this file use these
@@ -195,9 +200,6 @@ HASH ignore_table;
static struct my_option my_long_options[] =
{
- {"all", OPT_ALL, "Deprecated. Use --create-options instead.",
- &create_options, &create_options, 0, GET_BOOL, NO_ARG, 1,
- 0, 0, 0, 0, 0},
{"all-databases", 'A',
"Dump all the databases. This will be same as --databases with all databases selected.",
&opt_alldbs, &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
@@ -222,10 +224,10 @@ static struct my_option my_long_options[] =
{"allow-keywords", OPT_KEYWORDS,
"Allow creation of column names that are keywords.", &opt_keywords,
&opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-#ifdef __NETWARE__
- {"autoclose", OPT_AUTO_CLOSE, "Automatically close the screen on exit for Netware.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-#endif
+ {"apply-slave-statements", OPT_MYSQLDUMP_SLAVE_APPLY,
+ "Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.",
+ &opt_slave_apply, &opt_slave_apply, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory for character set files.", &charsets_dir,
&charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -233,13 +235,20 @@ static struct my_option my_long_options[] =
&opt_comments, &opt_comments, 0, GET_BOOL, NO_ARG,
1, 0, 0, 0, 0, 0},
{"compatible", OPT_COMPATIBLE,
- "Change the dump to be compatible with a given mode. By default tables are dumped in a format optimized for MySQL. Legal modes are: ansi, mysql323, mysql40, postgresql, oracle, mssql, db2, maxdb, no_key_options, no_table_options, no_field_options. One can use several modes separated by commas. Note: Requires MySQL server version 4.1.0 or higher. This option is ignored with earlier server versions.",
+ "Change the dump to be compatible with a given mode. By default tables "
+ "are dumped in a format optimized for MySQL. Legal modes are: ansi, "
+ "mysql323, mysql40, postgresql, oracle, mssql, db2, maxdb, no_key_options, "
+ "no_table_options, no_field_options. One can use several modes separated "
+ "by commas. Note: Requires MySQL server version 4.1.0 or higher. "
+ "This option is ignored with earlier server versions.",
&opt_compatible_mode_str, &opt_compatible_mode_str, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"compact", OPT_COMPACT,
- "Give less verbose output (useful for debugging). Disables structure comments and header/footer constructs. Enables options --skip-add-drop-table --skip-add-locks --skip-comments --skip-disable-keys --skip-set-charset.",
- &opt_compact, &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
- 0, 0},
+ "Give less verbose output (useful for debugging). Disables structure "
+ "comments and header/footer constructs. Enables options --skip-add-"
+ "drop-table --skip-add-locks --skip-comments --skip-disable-keys "
+ "--skip-set-charset.",
+ &opt_compact, &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"complete-insert", 'c', "Use complete insert statements.",
&opt_complete_insert, &opt_complete_insert, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -278,8 +287,22 @@ static struct my_option my_long_options[] =
&opt_delete_master_logs, &opt_delete_master_logs, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"disable-keys", 'K',
- "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", &opt_disable_keys,
+ "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER "
+ "TABLE tb_name ENABLE KEYS */; will be put in the output.", &opt_disable_keys,
&opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"dump-slave", OPT_MYSQLDUMP_SLAVE_DATA,
+ "This causes the binary log position and filename of the master to be "
+ "appended to the dumped data output. Setting the value to 1, will print"
+ "it as a CHANGE MASTER command in the dumped data output; if equal"
+ " to 2, that command will be prefixed with a comment symbol. "
+ "This option will turn --lock-all-tables on, unless "
+ "--single-transaction is specified too (in which case a "
+ "global read lock is only taken a short time at the beginning of the dump "
+ "- don't forget to read about --single-transaction below). In all cases "
+ "any action on logs will happen at the exact moment of the dump."
+ "Option automatically turns --lock-tables off.",
+ &opt_slave_data, &opt_slave_data, 0,
+ GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0},
{"events", 'E', "Dump events.",
&opt_events, &opt_events, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -288,24 +311,18 @@ static struct my_option my_long_options[] =
&extended_insert, &extended_insert, 0, GET_BOOL, NO_ARG,
1, 0, 0, 0, 0, 0},
{"fields-terminated-by", OPT_FTB,
- "Fields in the output file are terminated by the given string.",
- &fields_terminated, &fields_terminated, 0,
+ "Fields in the output file are terminated by the given string.",
+ &fields_terminated, &fields_terminated, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"fields-enclosed-by", OPT_ENC,
- "Fields in the output file are enclosed by the given character.",
- &enclosed, &enclosed, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
+ "Fields in the output file are enclosed by the given character.",
+ &enclosed, &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
{"fields-optionally-enclosed-by", OPT_O_ENC,
- "Fields in the output file are optionally enclosed by the given character.",
- &opt_enclosed, &opt_enclosed, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
- {"fields-escaped-by", OPT_ESC,
+ "Fields in the output file are optionally enclosed by the given character.",
+ &opt_enclosed, &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
+ {"fields-escaped-by", OPT_ESC,
"Fields in the output file are escaped by the given character.",
- &escaped, &escaped, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"first-slave", OPT_FIRST_SLAVE, "Deprecated, renamed to --lock-all-tables.",
- &opt_lock_all_tables, &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
- 0, 0, 0, 0, 0, 0},
+ &escaped, &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"flush-logs", 'F', "Flush logs file in server before starting dump. "
"Note that if you dump many databases at once (using the option "
"--databases= or --all-databases), the logs will be flushed for "
@@ -339,10 +356,15 @@ static struct my_option my_long_options[] =
"be specified with both database and table names, e.g., "
"--ignore-table=database.table.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"include-master-host-port", OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT,
+ "Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' "
+ "in dump produced with --dump-slave.", &opt_include_master_host_port,
+ &opt_include_master_host_port, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
{"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
&opt_ignore, &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
- {"lines-terminated-by", OPT_LTB,
+ {"lines-terminated-by", OPT_LTB,
"Lines in the output file are terminated by the given string.",
&lines_terminated, &lines_terminated, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -393,7 +415,7 @@ static struct my_option my_long_options[] =
NO_ARG, 0, 0, 0, 0, 0, 0},
{"no-data", 'd', "No row information.", &opt_no_data,
&opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"no-set-names", 'N',"Suppress the SET NAMES statement",
+ {"no-set-names", 'N', "Same as --skip-set-charset.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"opt", OPT_OPTIMIZE,
"Same as --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys. Enabled by default, disable with --skip-opt.",
@@ -423,18 +445,17 @@ static struct my_option my_long_options[] =
&opt_replace_into, &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},
+ "Direct output to a given file. This option should be used in systems "
+ "(e.g., DOS, Windows) that use carriage-return linefeed pairs (\\r\\n) "
+ "to separate text lines. This option ensures that only a single newline "
+ "is used.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"routines", 'R', "Dump stored routines (functions and procedures).",
- &opt_routines, &opt_routines, 0, GET_BOOL,
- NO_ARG, 0, 0, 0, 0, 0, 0},
+ &opt_routines, &opt_routines, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
{"set-charset", OPT_SET_CHARSET,
- "Add 'SET NAMES default_character_set' to the output. Enabled by default; suppress with --skip-set-charset.",
+ "Add 'SET NAMES default_character_set' to the output.",
&opt_set_charset, &opt_set_charset, 0, GET_BOOL, NO_ARG, 1,
0, 0, 0, 0, 0},
- {"set-variable", 'O',
- "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
- 0, 0, 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.", &shared_memory_base_name, &shared_memory_base_name,
@@ -493,6 +514,13 @@ static struct my_option my_long_options[] =
&where, &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
+ &opt_plugin_dir, &opt_plugin_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"default_auth", OPT_DEFAULT_AUTH,
+ "Default authentication client-side plugin to use.",
+ &opt_default_auth, &opt_default_auth, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -524,7 +552,6 @@ static int dump_tablespaces(char* ts_where);
static void print_comment(FILE *sql_file, my_bool is_error, const char *format,
...);
-#include <help_start.h>
/*
Print the supplied message if in verbose mode
@@ -547,6 +574,8 @@ static void verbose_msg(const char *fmt, ...)
vfprintf(stderr, fmt, args);
va_end(args);
+ fflush(stderr);
+
DBUG_VOID_RETURN;
}
@@ -568,7 +597,6 @@ static void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,DUMP_VERSION,
MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
- NETWARE_SET_SCREEN_MODE(1);
} /* print_version */
@@ -578,7 +606,6 @@ static void short_usage_sub(void)
printf("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n",
my_progname);
printf("OR %s [OPTIONS] --all-databases [OPTIONS]\n", my_progname);
- NETWARE_SET_SCREEN_MODE(1);
}
@@ -600,8 +627,6 @@ static void short_usage(void)
printf("For more options, use %s --help\n", my_progname);
}
-#include <help_end.h>
-
static void write_header(FILE *sql_file, char *db_name)
{
@@ -705,12 +730,6 @@ static void write_footer(FILE *sql_file)
} /* write_footer */
-static void free_table_ent(char *key)
-{
- my_free(key, MYF(0));
-}
-
-
uchar* get_table_key(const char *entry, size_t *length,
my_bool not_used __attribute__((unused)))
{
@@ -724,18 +743,13 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument)
{
switch (optid) {
-#ifdef __NETWARE__
- case OPT_AUTO_CLOSE:
- setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
- break;
-#endif
case 'p':
if (argument == disabled_my_option)
argument= (char*) ""; /* Don't require password */
if (argument)
{
char *start=argument;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_password);
opt_password=my_strdup(argument,MYF(MY_FAE));
while (*argument) *argument++= 'x'; /* Destroy argument */
if (*start)
@@ -791,19 +805,14 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case '?':
usage();
exit(0);
- case 'O':
- WARN_DEPRECATED(VER_CELOSIA, "--set-variable", "--variable-name=value");
- break;
- case (int) OPT_ALL:
- WARN_DEPRECATED(VER_CELOSIA, "--all", "--create-options");
- break;
- case (int) OPT_FIRST_SLAVE:
- WARN_DEPRECATED(VER_CELOSIA, "--first-slave", "--lock-all-tables");
- break;
case (int) OPT_MASTER_DATA:
if (!argument) /* work like in old versions */
opt_master_data= MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL;
break;
+ case (int) OPT_MYSQLDUMP_SLAVE_DATA:
+ if (!argument) /* work like in old versions */
+ opt_slave_data= MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL;
+ break;
case (int) OPT_OPTIMIZE:
extended_insert= opt_drop= opt_lock= quick= create_options=
opt_disable_keys= lock_tables= opt_set_charset= 1;
@@ -899,12 +908,12 @@ static int get_options(int *argc, char ***argv)
opt_net_buffer_length= *mysql_params->p_net_buffer_length;
md_result_file= stdout;
- load_defaults("my",load_default_groups,argc,argv);
+ if (load_defaults("my",load_default_groups,argc,argv))
+ return 1;
defaults_argv= *argv;
- if (hash_init(&ignore_table, charset_info, 16, 0, 0,
- (hash_get_key) get_table_key,
- (hash_free_key) free_table_ent, 0))
+ if (my_hash_init(&ignore_table, charset_info, 16, 0, 0,
+ (my_hash_get_key) get_table_key, my_free, 0))
return(EX_EOM);
/* Don't copy internal log tables */
if (my_hash_insert(&ignore_table,
@@ -937,6 +946,14 @@ static int get_options(int *argc, char ***argv)
return(EX_USAGE);
}
+ /* We don't delete master logs if slave data option */
+ if (opt_slave_data)
+ {
+ opt_lock_all_tables= !opt_single_transaction;
+ opt_master_data= 0;
+ opt_delete_master_logs= 0;
+ }
+
/* Ensure consistency of the set of binlog & locking options */
if (opt_delete_master_logs && !opt_master_data)
opt_master_data= MYSQL_OPT_MASTER_DATA_COMMENTED_SQL;
@@ -947,7 +964,10 @@ static int get_options(int *argc, char ***argv)
return(EX_USAGE);
}
if (opt_master_data)
+ {
opt_lock_all_tables= !opt_single_transaction;
+ opt_slave_data= 0;
+ }
if (opt_single_transaction || opt_lock_all_tables)
lock_tables= 0;
if (enclosed && opt_enclosed)
@@ -1320,120 +1340,68 @@ static int switch_character_set_results(MYSQL *mysql, const char *cs_name)
}
/**
- Rewrite CREATE TRIGGER statement, enclosing DEFINER clause in
- version-specific comment.
-
- This function parses the CREATE TRIGGER statement and encloses
- DEFINER-clause in version-specific comment:
- input query: CREATE DEFINER=a@b TRIGGER ...
- rewritten query: CREATE * / / *!50017 DEFINER=a@b * / / *!50003 TRIGGER ...
-
- @note This function will go away when WL#3995 is implemented.
-
- @param[in] trigger_def_str CREATE TRIGGER statement string.
- @param[in] trigger_def_length length of the trigger_def_str.
-
- @return pointer to the new allocated query string.
-*/
-
-static char *cover_definer_clause_in_trigger(const char *trigger_def_str,
- uint trigger_def_length)
-{
- char *query_str= NULL;
- char *definer_begin= my_case_str(trigger_def_str, trigger_def_length,
- C_STRING_WITH_LEN(" DEFINER"));
- char *definer_end;
-
- if (!definer_begin)
- return NULL;
-
- definer_end= my_case_str(definer_begin, strlen(definer_begin),
- C_STRING_WITH_LEN(" TRIGGER"));
-
- if (definer_end)
- {
- char *query_str_tail;
-
- /*
- Allocate memory for new query string: original string
- from SHOW statement and version-specific comments.
- */
- query_str= alloc_query_str(trigger_def_length + 23);
-
- query_str_tail= strnmov(query_str,
- trigger_def_str,
- definer_begin - trigger_def_str);
-
- query_str_tail= strmov(query_str_tail,
- "*/ /*!50017");
-
- query_str_tail= strnmov(query_str_tail,
- definer_begin,
- definer_end - definer_begin);
-
- query_str_tail= strxmov(query_str_tail,
- "*/ /*!50003",
- definer_end,
- NullS);
- }
-
- return query_str;
-}
-
-/**
- Rewrite CREATE FUNCTION or CREATE PROCEDURE statement, enclosing DEFINER
- clause in version-specific comment.
+ Rewrite statement, enclosing DEFINER clause in version-specific comment.
- This function parses the CREATE FUNCTION | PROCEDURE statement and
- encloses DEFINER-clause in version-specific comment:
+ This function parses any CREATE statement and encloses DEFINER-clause in
+ version-specific comment:
input query: CREATE DEFINER=a@b FUNCTION ...
rewritten query: CREATE * / / *!50020 DEFINER=a@b * / / *!50003 FUNCTION ...
@note This function will go away when WL#3995 is implemented.
- @param[in] def_str CREATE FUNCTION|PROCEDURE statement string.
- @param[in] def_str_length length of the def_str.
+ @param[in] stmt_str CREATE statement string.
+ @param[in] stmt_length Length of the stmt_str.
+ @param[in] definer_version_str Minimal MySQL version number when
+ DEFINER clause is supported in the
+ given statement.
+ @param[in] definer_version_length Length of definer_version_str.
+ @param[in] stmt_version_str Minimal MySQL version number when the
+ given statement is supported.
+ @param[in] stmt_version_length Length of stmt_version_str.
+ @param[in] keyword_str Keyword to look for after CREATE.
+ @param[in] keyword_length Length of keyword_str.
@return pointer to the new allocated query string.
*/
-static char *cover_definer_clause_in_sp(const char *def_str,
- uint def_str_length)
+static char *cover_definer_clause(const char *stmt_str,
+ uint stmt_length,
+ const char *definer_version_str,
+ uint definer_version_length,
+ const char *stmt_version_str,
+ uint stmt_version_length,
+ const char *keyword_str,
+ uint keyword_length)
{
- char *query_str= NULL;
- char *definer_begin= my_case_str(def_str, def_str_length,
+ char *definer_begin= my_case_str(stmt_str, stmt_length,
C_STRING_WITH_LEN(" DEFINER"));
- char *definer_end;
+ char *definer_end= NULL;
+
+ char *query_str= NULL;
+ char *query_ptr;
if (!definer_begin)
return NULL;
definer_end= my_case_str(definer_begin, strlen(definer_begin),
- C_STRING_WITH_LEN(" PROCEDURE"));
+ keyword_str, keyword_length);
if (!definer_end)
- {
- definer_end= my_case_str(definer_begin, strlen(definer_begin),
- C_STRING_WITH_LEN(" FUNCTION"));
- }
+ return NULL;
- if (definer_end)
- {
- char *query_str_tail;
+ /*
+ Allocate memory for new query string: original string
+ from SHOW statement and version-specific comments.
+ */
+ query_str= alloc_query_str(stmt_length + 23);
- /*
- Allocate memory for new query string: original string
- from SHOW statement and version-specific comments.
- */
- query_str= alloc_query_str(def_str_length + 23);
-
- query_str_tail= strnmov(query_str, def_str, definer_begin - def_str);
- query_str_tail= strmov(query_str_tail, "*/ /*!50020");
- query_str_tail= strnmov(query_str_tail, definer_begin,
- definer_end - definer_begin);
- query_str_tail= strxmov(query_str_tail, "*/ /*!50003",
- definer_end, NullS);
- }
+ query_ptr= strnmov(query_str, stmt_str, definer_begin - stmt_str);
+ query_ptr= strnmov(query_ptr, C_STRING_WITH_LEN("*/ /*!"));
+ query_ptr= strnmov(query_ptr, definer_version_str, definer_version_length);
+ query_ptr= strnmov(query_ptr, definer_begin, definer_end - definer_begin);
+ query_ptr= strnmov(query_ptr, C_STRING_WITH_LEN("*/ /*!"));
+ query_ptr= strnmov(query_ptr, stmt_version_str, stmt_version_length);
+ query_ptr= strxmov(query_ptr, definer_end, NullS);
return query_str;
}
@@ -1465,9 +1433,9 @@ static void free_resources()
{
if (md_result_file && md_result_file != stdout)
my_fclose(md_result_file, MYF(0));
- my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
- if (hash_inited(&ignore_table))
- hash_free(&ignore_table);
+ my_free(opt_password);
+ if (my_hash_inited(&ignore_table))
+ my_hash_free(&ignore_table);
if (extended_insert)
dynstr_free(&extended_row);
if (insert_pat_inited)
@@ -1518,6 +1486,13 @@ static int connect_to_db(char *host, char *user,char *passwd)
mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset);
+
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(&mysql_connection, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (opt_default_auth && *opt_default_auth)
+ mysql_options(&mysql_connection, MYSQL_DEFAULT_AUTH, opt_default_auth);
+
if (!(mysql= mysql_real_connect(&mysql_connection,host,user,passwd,
NULL,opt_mysql_port,opt_mysql_unix_port,
0)))
@@ -1579,7 +1554,7 @@ static void unescape(FILE *file,char *pos,uint length)
fputs(tmp, file);
fputc('\'', file);
check_io(file);
- my_free(tmp, MYF(MY_WME));
+ my_free(tmp);
DBUG_VOID_RETURN;
} /* unescape */
@@ -2123,6 +2098,8 @@ static uint dump_events_for_db(char *db)
*/
if (strlen(row[3]) != 0)
{
+ char *query_str;
+
if (opt_drop)
fprintf(sql_file, "/*!50106 DROP EVENT IF EXISTS %s */%s\n",
event_name, delimiter);
@@ -2149,31 +2126,36 @@ static uint dump_events_for_db(char *db)
row[4], /* character_set_results */
row[5]); /* collation_connection */
}
- else
- {
- /*
- mysqldump is being run against the server, that does not
- provide character set information in SHOW CREATE
- statements.
+ else
+ {
+ /*
+ mysqldump is being run against the server, that does not
+ provide character set information in SHOW CREATE
+ statements.
- NOTE: the dump may be incorrect, since character set
- information is required in order to restore event properly.
- */
+ NOTE: the dump may be incorrect, since character set
+ information is required in order to restore event properly.
+ */
- fprintf(sql_file,
- "--\n"
- "-- WARNING: old server version. "
- "The following dump may be incomplete.\n"
- "--\n");
- }
+ fprintf(sql_file,
+ "--\n"
+ "-- WARNING: old server version. "
+ "The following dump may be incomplete.\n"
+ "--\n");
+ }
switch_sql_mode(sql_file, delimiter, row[1]);
switch_time_zone(sql_file, delimiter, row[2]);
+ query_str= cover_definer_clause(row[3], strlen(row[3]),
+ C_STRING_WITH_LEN("50117"),
+ C_STRING_WITH_LEN("50106"),
+ C_STRING_WITH_LEN(" EVENT"));
+
fprintf(sql_file,
"/*!50106 %s */ %s\n",
- (const char *) row[3],
+ (const char *) (query_str != NULL ? query_str : row[3]),
(const char *) delimiter);
restore_time_zone(sql_file, delimiter);
@@ -2212,7 +2194,7 @@ static uint dump_events_for_db(char *db)
mysql_free_result(event_list_res);
if (lock_tables)
- VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+ (void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES");
DBUG_RETURN(0);
}
@@ -2352,7 +2334,16 @@ static uint dump_routines_for_db(char *db)
fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */;\n",
routine_type[i], routine_name);
- query_str= cover_definer_clause_in_sp(row[2], strlen(row[2]));
+ query_str= cover_definer_clause(row[2], strlen(row[2]),
+ C_STRING_WITH_LEN("50020"),
+ C_STRING_WITH_LEN("50003"),
+ C_STRING_WITH_LEN(" FUNCTION"));
+
+ if (!query_str)
+ query_str= cover_definer_clause(row[2], strlen(row[2]),
+ C_STRING_WITH_LEN("50020"),
+ C_STRING_WITH_LEN("50003"),
+ C_STRING_WITH_LEN(" PROCEDURE"));
if (mysql_num_fields(routine_res) >= 6)
{
@@ -2408,7 +2399,7 @@ static uint dump_routines_for_db(char *db)
}
}
- my_free(query_str, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(query_str);
}
} /* end of routine printing */
mysql_free_result(routine_res);
@@ -2428,7 +2419,7 @@ static uint dump_routines_for_db(char *db)
DBUG_RETURN(1);
if (lock_tables)
- VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+ (void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES");
DBUG_RETURN(0);
}
@@ -2565,6 +2556,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
if (strcmp(field->name, "View") == 0)
{
char *scv_buff= NULL;
+ my_ulonglong n_cols;
verbose_msg("-- It's a view, create dummy table for view\n");
@@ -2579,8 +2571,8 @@ static uint get_table_structure(char *table, char *db, char *table_type,
the same name in order to satisfy views that depend on this view.
The table will be removed when the actual view is created.
- The properties of each column, aside from the data type, are not
- preserved in this temporary table, because they are not necessary.
+ The properties of each column, are not preserved in this temporary
+ table, because they are not necessary.
This will not be necessary once we can determine dependencies
between views and can simply dump them in the appropriate order.
@@ -2600,15 +2592,30 @@ static uint get_table_structure(char *table, char *db, char *table_type,
if (mysql_errno(mysql) == ER_VIEW_INVALID)
fprintf(sql_file, "\n-- failed on view %s: %s\n\n", result_table, scv_buff ? scv_buff : "");
- my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(scv_buff);
DBUG_RETURN(0);
}
else
- my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(scv_buff);
- if (mysql_num_rows(result))
+ n_cols= mysql_num_rows(result);
+ if (0 != n_cols)
{
+
+ /*
+ The actual formula is based on the column names and how the .FRM
+ files are stored and is too volatile to be repeated here.
+ Thus we simply warn the user if the columns exceed a limit we
+ know works most of the time.
+ */
+ if (n_cols >= 1000)
+ fprintf(stderr,
+ "-- Warning: Creating a stand-in table for view %s may"
+ " fail when replaying the dump file produced because "
+ "of the number of columns exceeding 1000. Exercise "
+ "caution when replaying the produced dump file.\n",
+ table);
if (opt_drop)
{
/*
@@ -2635,14 +2642,19 @@ static uint get_table_structure(char *table, char *db, char *table_type,
row= mysql_fetch_row(result);
- fprintf(sql_file, " %s %s", quote_name(row[0], name_buff, 0),
- row[1]);
+ /*
+ The actual column type doesn't matter anyway, since the table will
+ be dropped at run time.
+ We do tinyint to avoid hitting the row size limit.
+ */
+ fprintf(sql_file, " %s tinyint NOT NULL",
+ quote_name(row[0], name_buff, 0));
while((row= mysql_fetch_row(result)))
{
/* col name, col type */
- fprintf(sql_file, ",\n %s %s",
- quote_name(row[0], name_buff, 0), row[1]);
+ fprintf(sql_file, ",\n %s tinyint NOT NULL",
+ quote_name(row[0], name_buff, 0));
}
/*
@@ -3083,9 +3095,10 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs,
continue;
}
- query_str= cover_definer_clause_in_trigger(row[2], strlen(row[2]));
-
-
+ query_str= cover_definer_clause(row[2], strlen(row[2]),
+ C_STRING_WITH_LEN("50017"),
+ C_STRING_WITH_LEN("50003"),
+ C_STRING_WITH_LEN(" TRIGGER"));
if (switch_db_collation(sql_file, db_name, ";",
db_cl_name, row[5], &db_cl_altered))
DBUG_RETURN(TRUE);
@@ -3112,7 +3125,7 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs,
DBUG_RETURN(TRUE);
}
- my_free(query_str, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(query_str);
}
DBUG_RETURN(FALSE);
@@ -3597,7 +3610,7 @@ static void dump_table(char *table, char *db)
{
if (length)
{
- if (!IS_NUM_FIELD(field))
+ if (!(field->flags & NUM_FLAG))
{
/*
"length * 2 + 2" is OK for both HEX and non-HEX modes:
@@ -3665,7 +3678,7 @@ static void dump_table(char *table, char *db)
}
if (row[i])
{
- if (!IS_NUM_FIELD(field))
+ if (!(field->flags & NUM_FLAG))
{
if (opt_xml)
{
@@ -4102,8 +4115,12 @@ static int dump_all_databases()
return 1;
while ((row= mysql_fetch_row(tableres)))
{
- if (mysql_get_server_version(mysql) >= 50003 &&
- !my_strcasecmp(&my_charset_latin1, row[0], "information_schema"))
+ if (mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, row[0], INFORMATION_SCHEMA_DB_NAME))
+ continue;
+
+ if (mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME))
continue;
if (dump_all_tables_in_db(row[0]))
@@ -4120,8 +4137,12 @@ static int dump_all_databases()
}
while ((row= mysql_fetch_row(tableres)))
{
- if (mysql_get_server_version(mysql) >= 50003 &&
- !my_strcasecmp(&my_charset_latin1, row[0], "information_schema"))
+ if (mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, row[0], INFORMATION_SCHEMA_DB_NAME))
+ continue;
+
+ if (mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME))
continue;
if (dump_all_views_in_db(row[0]))
@@ -4265,7 +4286,7 @@ static int init_dumping(char *database, int init_func(char*))
my_bool include_table(const uchar *hash_key, size_t len)
{
- return !hash_search(&ignore_table, hash_key, len);
+ return ! my_hash_search(&ignore_table, hash_key, len);
}
@@ -4327,6 +4348,8 @@ static int dump_all_tables_in_db(char *database)
if (mysql_refresh(mysql, REFRESH_LOG))
DB_error(mysql, "when doing refresh");
/* We shall continue here, if --force was given */
+ else
+ verbose_msg("-- dump_all_tables_in_db : logs flushed successfully!\n");
}
while ((table= getTableName(0)))
{
@@ -4334,7 +4357,7 @@ static int dump_all_tables_in_db(char *database)
if (include_table((uchar*) hash_key, end - hash_key))
{
dump_table(table,database);
- my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(order_by);
order_by= 0;
if (opt_dump_triggers && mysql_get_server_version(mysql) >= 50009)
{
@@ -4363,7 +4386,7 @@ static int dump_all_tables_in_db(char *database)
check_io(md_result_file);
}
if (lock_tables)
- VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+ (void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES");
if (flush_privileges && using_mysql_db == 0)
{
fprintf(md_result_file,"\n--\n-- Flush Grant Tables \n--\n");
@@ -4424,6 +4447,8 @@ static my_bool dump_all_views_in_db(char *database)
if (mysql_refresh(mysql, REFRESH_LOG))
DB_error(mysql, "when doing refresh");
/* We shall continue here, if --force was given */
+ else
+ verbose_msg("-- dump_all_views_in_db : logs flushed successfully!\n");
}
while ((table= getTableName(0)))
{
@@ -4437,7 +4462,7 @@ static my_bool dump_all_views_in_db(char *database)
check_io(md_result_file);
}
if (lock_tables)
- VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+ (void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES");
return 0;
} /* dump_all_tables_in_db */
@@ -4533,10 +4558,12 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
}
end= pos;
- /* Can't LOCK TABLES in INFORMATION_SCHEMA, so don't try. */
+ /* Can't LOCK TABLES in I_S / P_S, so don't try. */
if (lock_tables &&
- !(mysql_get_server_version(mysql) >= 50003 &&
- !my_strcasecmp(&my_charset_latin1, db, "information_schema")))
+ !(mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, db, INFORMATION_SCHEMA_DB_NAME)) &&
+ !(mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, db, PERFORMANCE_SCHEMA_DB_NAME)))
{
if (mysql_real_query(mysql, lock_tables_query.str,
lock_tables_query.length-1))
@@ -4560,6 +4587,8 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
DB_error(mysql, "when doing refresh");
}
/* We shall countinue here, if --force was given */
+ else
+ verbose_msg("-- dump_selected_tables : logs flushed successfully!\n");
}
if (opt_xml)
print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NullS);
@@ -4599,7 +4628,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
dump_routines_for_db(db);
}
free_root(&root, MYF(0));
- my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(order_by);
order_by= 0;
if (opt_xml)
{
@@ -4607,7 +4636,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
check_io(md_result_file);
}
if (lock_tables)
- VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+ (void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES");
DBUG_RETURN(0);
} /* dump_selected_tables */
@@ -4650,6 +4679,130 @@ static int do_show_master_status(MYSQL *mysql_con)
return 0;
}
+static int do_stop_slave_sql(MYSQL *mysql_con)
+{
+ MYSQL_RES *slave;
+ /* We need to check if the slave sql is running in the first place */
+ if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
+ return(1);
+ else
+ {
+ MYSQL_ROW row= mysql_fetch_row(slave);
+ if (row && row[11])
+ {
+ /* if SLAVE SQL is not running, we don't stop it */
+ if (!strcmp(row[11],"No"))
+ {
+ mysql_free_result(slave);
+ /* Silently assume that they don't have the slave running */
+ return(0);
+ }
+ }
+ }
+ mysql_free_result(slave);
+
+ /* now, stop slave if running */
+ if (mysql_query_with_error_report(mysql_con, 0, "STOP SLAVE SQL_THREAD"))
+ return(1);
+
+ return(0);
+}
+
+static int add_stop_slave(void)
+{
+ if (opt_comments)
+ fprintf(md_result_file,
+ "\n--\n-- stop slave statement to make a recovery dump)\n--\n\n");
+ fprintf(md_result_file, "STOP SLAVE;\n");
+ return(0);
+}
+
+static int add_slave_statements(void)
+{
+ if (opt_comments)
+ fprintf(md_result_file,
+ "\n--\n-- start slave statement to make a recovery dump)\n--\n\n");
+ fprintf(md_result_file, "START SLAVE;\n");
+ return(0);
+}
+
+static int do_show_slave_status(MYSQL *mysql_con)
+{
+ MYSQL_RES *slave;
+ const char *comment_prefix=
+ (opt_slave_data == MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
+ if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
+ {
+ if (!ignore_errors)
+ {
+ /* SHOW SLAVE STATUS reports nothing and --force is not enabled */
+ my_printf_error(0, "Error: Slave not set up", MYF(0));
+ }
+ mysql_free_result(slave);
+ return 1;
+ }
+ else
+ {
+ MYSQL_ROW row= mysql_fetch_row(slave);
+ if (row && row[9] && row[21])
+ {
+ /* SHOW MASTER STATUS reports file and position */
+ if (opt_comments)
+ fprintf(md_result_file,
+ "\n--\n-- Position to start replication or point-in-time "
+ "recovery from (the master of this slave)\n--\n\n");
+
+ fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix);
+
+ if (opt_include_master_host_port)
+ {
+ if (row[1])
+ fprintf(md_result_file, "MASTER_HOST='%s', ", row[1]);
+ if (row[3])
+ fprintf(md_result_file, "MASTER_PORT='%s', ", row[3]);
+ }
+ fprintf(md_result_file,
+ "MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]);
+
+ check_io(md_result_file);
+ }
+ mysql_free_result(slave);
+ }
+ return 0;
+}
+
+static int do_start_slave_sql(MYSQL *mysql_con)
+{
+ MYSQL_RES *slave;
+ /* We need to check if the slave sql is stopped in the first place */
+ if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
+ return(1);
+ else
+ {
+ MYSQL_ROW row= mysql_fetch_row(slave);
+ if (row && row[11])
+ {
+ /* if SLAVE SQL is not running, we don't start it */
+ if (!strcmp(row[11],"Yes"))
+ {
+ mysql_free_result(slave);
+ /* Silently assume that they don't have the slave running */
+ return(0);
+ }
+ }
+ }
+ mysql_free_result(slave);
+
+ /* now, start slave if stopped */
+ if (mysql_query_with_error_report(mysql_con, 0, "START SLAVE"))
+ {
+ my_printf_error(0, "Error: Unable to start slave", MYF(0));
+ return 1;
+ }
+ return(0);
+}
+
+
static int do_flush_tables_read_lock(MYSQL *mysql_con)
{
@@ -4716,6 +4869,7 @@ static int purge_bin_logs_to(MYSQL *mysql_con, char* log_name)
static int start_transaction(MYSQL *mysql_con)
{
+ verbose_msg("-- Starting transaction...\n");
/*
We use BEGIN for old servers. --single-transaction --master-data will fail
on old servers, but that's ok as it was already silently broken (it didn't
@@ -4770,7 +4924,7 @@ static ulong find_set(TYPELIB *lib, const char *x, uint length,
for (; pos != end && *pos != ','; pos++) ;
var_len= (uint) (pos - start);
strmake(buff, start, min(sizeof(buff) - 1, var_len));
- find= find_type(buff, lib, var_len);
+ find= find_type(buff, lib, FIND_TYPE_BASIC);
if (!find)
{
*err_pos= (char*) start;
@@ -5316,26 +5470,49 @@ int main(int argc, char **argv)
if (!path)
write_header(md_result_file, *argv);
- if ((opt_lock_all_tables || opt_master_data) &&
+ if (opt_slave_data && do_stop_slave_sql(mysql))
+ goto err;
+
+ if ((opt_lock_all_tables || opt_master_data ||
+ (opt_single_transaction && flush_logs)) &&
do_flush_tables_read_lock(mysql))
goto err;
- if (opt_single_transaction && start_transaction(mysql))
- goto err;
- if (opt_delete_master_logs)
+
+ /*
+ Flush logs before starting transaction since
+ this causes implicit commit starting mysql-5.5.
+ */
+ if (opt_lock_all_tables || opt_master_data ||
+ (opt_single_transaction && flush_logs) ||
+ opt_delete_master_logs)
{
- if (mysql_refresh(mysql, REFRESH_LOG) ||
- get_bin_log_name(mysql, bin_log_name, sizeof(bin_log_name)))
- goto err;
+ if (flush_logs || opt_delete_master_logs)
+ {
+ if (mysql_refresh(mysql, REFRESH_LOG))
+ goto err;
+ verbose_msg("-- main : logs flushed successfully!\n");
+ }
+
+ /* Not anymore! That would not be sensible. */
flush_logs= 0;
}
- if (opt_lock_all_tables || opt_master_data)
+
+ if (opt_delete_master_logs)
{
- if (flush_logs && mysql_refresh(mysql, REFRESH_LOG))
+ if (get_bin_log_name(mysql, bin_log_name, sizeof(bin_log_name)))
goto err;
- flush_logs= 0; /* not anymore; that would not be sensible */
}
+
+ if (opt_single_transaction && start_transaction(mysql))
+ goto err;
+
+ /* Add 'STOP SLAVE to beginning of dump */
+ if (opt_slave_apply && add_stop_slave())
+ goto err;
if (opt_master_data && do_show_master_status(mysql))
goto err;
+ if (opt_slave_data && do_show_slave_status(mysql))
+ goto err;
if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */
goto err;
@@ -5363,6 +5540,14 @@ int main(int argc, char **argv)
dump_databases(argv);
}
+ /* if --dump-slave , start the slave sql thread */
+ if (opt_slave_data && do_start_slave_sql(mysql))
+ goto err;
+
+ /* add 'START SLAVE' to end of dump */
+ if (opt_slave_apply && add_slave_statements())
+ goto err;
+
/* ensure dumped data flushed */
if (md_result_file && fflush(md_result_file))
{
@@ -5375,7 +5560,7 @@ int main(int argc, char **argv)
goto err;
#ifdef HAVE_SMEM
- my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(shared_memory_base_name);
#endif
/*
No reason to explicitely COMMIT the transaction, neither to explicitely
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index a739c5aded0..2045c94619b 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -28,6 +28,8 @@
#include <my_pthread.h>
#endif
+#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
+
/* Global Thread counter */
uint counter;
@@ -36,8 +38,6 @@ pthread_mutex_t counter_mutex;
pthread_cond_t count_threshhold;
#endif
-#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
-
static void db_error_with_table(MYSQL *mysql, char *table);
static void db_error(MYSQL *mysql);
static char *field_escape(char *to,const char *from,uint length);
@@ -53,11 +53,11 @@ static char *opt_password=0, *current_user=0,
*current_host=0, *current_db=0, *fields_terminated=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0,
*escaped=0, *opt_columns=0,
- *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
+ *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME;
static uint opt_mysql_port= 0, opt_protocol= 0;
static char * opt_mysql_unix_port=0;
+static char *opt_plugin_dir= 0, *opt_default_auth= 0;
static longlong opt_ignore_lines= -1;
-static CHARSET_INFO *charset_info= &my_charset_latin1;
#include <sslopt-vars.h>
#ifdef HAVE_SMEM
@@ -66,10 +66,6 @@ static char *shared_memory_base_name=0;
static struct my_option my_long_options[] =
{
-#ifdef __NETWARE__
- {"autoclose", OPT_AUTO_CLOSE, "Automatically close the screen on exit for Netware.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-#endif
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory for character set files.", &charsets_dir,
&charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -91,6 +87,10 @@ static struct my_option my_long_options[] =
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
&debug_info_flag, &debug_info_flag,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"default_auth", OPT_DEFAULT_AUTH,
+ "Default authentication client-side plugin to use.",
+ &opt_default_auth, &opt_default_auth, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"delete", 'd', "First delete all rows from table.", &opt_delete,
&opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"fields-terminated-by", OPT_FTB,
@@ -140,6 +140,9 @@ static struct my_option my_long_options[] =
{"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
+ &opt_plugin_dir, &opt_plugin_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"port", 'P', "Port number to use for connection or 0 for default to, in "
"order of preference, my.cnf, $MYSQL_TCP_PORT, "
#if MYSQL_PORT_DEFAULT == 0
@@ -183,13 +186,11 @@ static struct my_option my_long_options[] =
static const char *load_default_groups[]= { "mysqlimport","client",0 };
-#include <help_start.h>
static void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s (%s)\n" ,my_progname,
IMPORT_VERSION, MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
- NETWARE_SET_SCREEN_MODE(1);
}
@@ -210,25 +211,19 @@ file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
my_print_variables(my_long_options);
}
-#include <help_end.h>
static my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument)
{
switch(optid) {
-#ifdef __NETWARE__
- case OPT_AUTO_CLOSE:
- setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
- break;
-#endif
case 'p':
if (argument == disabled_my_option)
argument= (char*) ""; /* Don't require password */
if (argument)
{
char *start=argument;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_password);
opt_password=my_strdup(argument,MYF(MY_FAE));
while (*argument) *argument++= 'x'; /* Destroy argument */
if (*start)
@@ -284,10 +279,6 @@ static int get_options(int *argc, char ***argv)
fprintf(stderr, "You can't use --ignore (-i) and --replace (-r) at the same time.\n");
return(1);
}
- if (strcmp(default_charset, charset_info->csname) &&
- !(charset_info= get_charset_by_csname(default_charset,
- MY_CS_PRIMARY, MYF(MY_WME))))
- exit(1);
if (*argc < 2)
{
usage();
@@ -442,6 +433,14 @@ static MYSQL *db_connect(char *host, char *database,
if (shared_memory_base_name)
mysql_options(mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
+
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (opt_default_auth && *opt_default_auth)
+ mysql_options(mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
+
+ mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset);
if (!(mysql_real_connect(mysql,host,user,passwd,
database,opt_mysql_port,opt_mysql_unix_port,
0)))
@@ -598,7 +597,8 @@ int main(int argc, char **argv)
char **argv_to_free;
MY_INIT(argv[0]);
- load_defaults("my",load_default_groups,&argc,&argv);
+ if (load_defaults("my",load_default_groups,&argc,&argv))
+ return 1;
/* argv is changed in the program */
argv_to_free= argv;
if (get_options(&argc, &argv))
@@ -616,8 +616,8 @@ int main(int argc, char **argv)
pthread_attr_setdetachstate(&attr,
PTHREAD_CREATE_DETACHED);
- VOID(pthread_mutex_init(&counter_mutex, NULL));
- VOID(pthread_cond_init(&count_threshhold, NULL));
+ pthread_mutex_init(&counter_mutex, NULL);
+ pthread_cond_init(&count_threshhold, NULL);
for (counter= 0; *argv != NULL; argv++) /* Loop through tables */
{
@@ -656,8 +656,8 @@ int main(int argc, char **argv)
pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
}
pthread_mutex_unlock(&counter_mutex);
- VOID(pthread_mutex_destroy(&counter_mutex));
- VOID(pthread_cond_destroy(&count_threshhold));
+ pthread_mutex_destroy(&counter_mutex);
+ pthread_cond_destroy(&count_threshhold);
pthread_attr_destroy(&attr);
}
else
@@ -684,9 +684,9 @@ int main(int argc, char **argv)
exitcode= error;
db_disconnect(current_host, mysql);
}
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_password);
#ifdef HAVE_SMEM
- my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(shared_memory_base_name);
#endif
free_defaults(argv_to_free);
my_end(my_end_arg);
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index 1656ec71af8..5677681541b 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -35,7 +35,8 @@ static my_bool tty_password= 0, opt_table_type= 0;
static my_bool debug_info_flag= 0, debug_check_flag= 0;
static uint my_end_arg= 0;
static uint opt_verbose=0;
-static char *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
+static char *default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME;
+static char *opt_plugin_dir= 0, *opt_default_auth= 0;
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
@@ -66,7 +67,9 @@ int main(int argc, char **argv)
char *wild;
MYSQL mysql;
MY_INIT(argv[0]);
- load_defaults("my",load_default_groups,&argc,&argv);
+ if (load_defaults("my",load_default_groups,&argc,&argv))
+ exit(1);
+
get_options(&argc,&argv);
wild=0;
@@ -124,6 +127,12 @@ int main(int argc, char **argv)
#endif
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(&mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (opt_default_auth && *opt_default_auth)
+ mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
+
if (!(mysql_real_connect(&mysql,host,user,opt_password,
(first_argument_uses_wildcards) ? "" :
argv[0],opt_mysql_port,opt_mysql_unix_port,
@@ -150,10 +159,9 @@ int main(int argc, char **argv)
break;
}
mysql_close(&mysql); /* Close & free connection */
- if (opt_password)
- my_free(opt_password,MYF(0));
+ my_free(opt_password);
#ifdef HAVE_SMEM
- my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(shared_memory_base_name);
#endif
my_end(my_end_arg);
exit(error ? 1 : 0);
@@ -162,10 +170,6 @@ int main(int argc, char **argv)
static struct my_option my_long_options[] =
{
-#ifdef __NETWARE__
- {"autoclose", OPT_AUTO_CLOSE, "Automatically close the screen on exit for Netware.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-#endif
{"character-sets-dir", 'c', "Directory for character set files.",
&charsets_dir, &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0,
0, 0, 0, 0, 0},
@@ -187,6 +191,10 @@ static struct my_option my_long_options[] =
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
&debug_info_flag, &debug_info_flag,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"default_auth", OPT_DEFAULT_AUTH,
+ "Default authentication client-side plugin to use.",
+ &opt_default_auth, &opt_default_auth, 0,
+ GET_STR, REQUIRED_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.", &host, &host, 0, GET_STR,
@@ -200,6 +208,9 @@ static struct my_option my_long_options[] =
"Password to use when connecting to server. If password is not given, it's "
"solicited on the tty.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
+ &opt_plugin_dir, &opt_plugin_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"port", 'P', "Port number to use for connection or 0 for default to, in "
"order of preference, my.cnf, $MYSQL_TCP_PORT, "
#if MYSQL_PORT_DEFAULT == 0
@@ -242,14 +253,11 @@ static struct my_option my_long_options[] =
{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);
- NETWARE_SET_SCREEN_MODE(1);
}
@@ -271,18 +279,12 @@ are shown.");
my_print_variables(my_long_options);
}
-#include <help_end.h>
static my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument)
{
switch(optid) {
-#ifdef __NETWARE__
- case OPT_AUTO_CLOSE:
- setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
- break;
-#endif
case 'v':
opt_verbose++;
break;
@@ -292,7 +294,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
if (argument)
{
char *start=argument;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_password);
opt_password=my_strdup(argument,MYF(MY_FAE));
while (*argument) *argument++= 'x'; /* Destroy argument */
if (*start)
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
index 4c4dbafc24d..ff5d2ddaf26 100644
--- a/client/mysqlslap.c
+++ b/client/mysqlslap.c
@@ -13,12 +13,8 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
- original idea: Brian Aker via playing with ab for too many years
- coded by: Patrick Galbraith
*/
-
/*
MySQL Slap
@@ -128,6 +124,9 @@ static char *host= NULL, *opt_password= NULL, *user= NULL,
*pre_system= NULL,
*post_system= NULL,
*opt_mysql_unix_port= NULL;
+static char *opt_plugin_dir= 0, *opt_default_auth= 0;
+static uint opt_enable_cleartext_plugin= 0;
+static my_bool using_opt_enable_cleartext_plugin= 0;
const char *delimiter= "\n";
@@ -302,7 +301,11 @@ int main(int argc, char **argv)
MY_INIT(argv[0]);
- load_defaults("my",load_default_groups,&argc,&argv);
+ if (load_defaults("my",load_default_groups,&argc,&argv))
+ {
+ my_end(0);
+ exit(1);
+ }
defaults_argv=argv;
if (get_options(&argc,&argv))
{
@@ -341,6 +344,15 @@ int main(int argc, char **argv)
#endif
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(&mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (opt_default_auth && *opt_default_auth)
+ mysql_options(&mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
+
+ if (using_opt_enable_cleartext_plugin)
+ mysql_options(&mysql, MYSQL_ENABLE_CLEARTEXT_PLUGIN,
+ (char*) &opt_enable_cleartext_plugin);
if (!opt_only_print)
{
if (!(mysql_real_connect(&mysql, host, user, opt_password,
@@ -355,10 +367,10 @@ int main(int argc, char **argv)
}
}
- VOID(pthread_mutex_init(&counter_mutex, NULL));
- VOID(pthread_cond_init(&count_threshhold, NULL));
- VOID(pthread_mutex_init(&sleeper_mutex, NULL));
- VOID(pthread_cond_init(&sleep_threshhold, NULL));
+ pthread_mutex_init(&counter_mutex, NULL);
+ pthread_cond_init(&count_threshhold, NULL);
+ pthread_mutex_init(&sleeper_mutex, NULL);
+ pthread_cond_init(&sleep_threshhold, NULL);
/* Main iterations loop */
eptr= engine_options;
@@ -389,19 +401,17 @@ int main(int argc, char **argv)
} while (eptr ? (eptr= eptr->next) : 0);
- VOID(pthread_mutex_destroy(&counter_mutex));
- VOID(pthread_cond_destroy(&count_threshhold));
- VOID(pthread_mutex_destroy(&sleeper_mutex));
- VOID(pthread_cond_destroy(&sleep_threshhold));
+ pthread_mutex_destroy(&counter_mutex);
+ pthread_cond_destroy(&count_threshhold);
+ pthread_mutex_destroy(&sleeper_mutex);
+ pthread_cond_destroy(&sleep_threshhold);
if (!opt_only_print)
mysql_close(&mysql); /* Close & free connection */
/* now free all the strings we created */
- if (opt_password)
- my_free(opt_password, MYF(0));
-
- my_free(concurrency, MYF(0));
+ my_free(opt_password);
+ my_free(concurrency);
statement_cleanup(create_statements);
statement_cleanup(query_statements);
@@ -410,8 +420,7 @@ int main(int argc, char **argv)
option_cleanup(engine_options);
#ifdef HAVE_SMEM
- if (shared_memory_base_name)
- my_free(shared_memory_base_name, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(shared_memory_base_name);
#endif
free_defaults(defaults_argv);
my_end(my_end_arg);
@@ -503,7 +512,7 @@ void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr)
if (opt_csv_str)
print_conclusions_csv(&conclusion);
- my_free(head_sptr, MYF(0));
+ my_free(head_sptr);
}
@@ -587,6 +596,10 @@ static struct my_option my_long_options[] =
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"debug-info", 'T', "Print some debug info at exit.", &debug_info_flag,
&debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"default_auth", OPT_DEFAULT_AUTH,
+ "Default authentication client-side plugin to use.",
+ &opt_default_auth, &opt_default_auth, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"delimiter", 'F',
"Delimiter to use in SQL statements supplied in file or command line.",
&delimiter, &delimiter, 0, GET_STR, REQUIRED_ARG,
@@ -595,6 +608,10 @@ static struct my_option my_long_options[] =
"Detach (close and reopen) connections after X number of requests.",
&detach_rate, &detach_rate, 0, GET_UINT, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
+ {"enable_cleartext_plugin", OPT_ENABLE_CLEARTEXT_PLUGIN,
+ "Enable/disable the clear text authentication plugin.",
+ &opt_enable_cleartext_plugin, &opt_enable_cleartext_plugin,
+ 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"engine", 'e', "Storage engine to use for creating the table.",
&default_engine, &default_engine, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -628,6 +645,9 @@ static struct my_option my_long_options[] =
{"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
+ &opt_plugin_dir, &opt_plugin_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"port", 'P', "Port number to use for connection.", &opt_mysql_port,
&opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
0},
@@ -680,8 +700,6 @@ static struct my_option my_long_options[] =
};
-#include <help_start.h>
-
static void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname, SLAP_VERSION,
@@ -699,7 +717,6 @@ static void usage(void)
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)),
@@ -707,11 +724,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
{
DBUG_ENTER("get_one_option");
switch(optid) {
-#ifdef __NETWARE__
- case OPT_AUTO_CLOSE:
- setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
- break;
-#endif
case 'v':
verbose++;
break;
@@ -721,7 +733,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
if (argument)
{
char *start= argument;
- my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_password);
opt_password= my_strdup(argument,MYF(MY_FAE));
while (*argument) *argument++= 'x'; /* Destroy argument */
if (*start)
@@ -758,6 +770,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case 'I': /* Info */
usage();
exit(0);
+ case OPT_ENABLE_CLEARTEXT_PLUGIN:
+ using_opt_enable_cleartext_plugin= TRUE;
+ break;
}
DBUG_RETURN(0);
}
@@ -1207,7 +1222,7 @@ get_options(int *argc,char ***argv)
if (opt_csv_str[0] == '-')
{
- csv_file= fileno(stdout);
+ csv_file= my_fileno(stdout);
}
else
{
@@ -1370,7 +1385,7 @@ get_options(int *argc,char ***argv)
tmp_string[sbuf.st_size]= '\0';
my_close(data_file,MYF(0));
parse_delimiter(tmp_string, &create_statements, delimiter[0]);
- my_free(tmp_string, MYF(0));
+ my_free(tmp_string);
}
else if (create_string)
{
@@ -1399,7 +1414,7 @@ get_options(int *argc,char ***argv)
if (user_supplied_query)
actual_queries= parse_delimiter(tmp_string, &query_statements,
delimiter[0]);
- my_free(tmp_string, MYF(0));
+ my_free(tmp_string);
}
else if (user_supplied_query)
{
@@ -1430,7 +1445,7 @@ get_options(int *argc,char ***argv)
if (user_supplied_pre_statements)
(void)parse_delimiter(tmp_string, &pre_statements,
delimiter[0]);
- my_free(tmp_string, MYF(0));
+ my_free(tmp_string);
}
else if (user_supplied_pre_statements)
{
@@ -1461,7 +1476,7 @@ get_options(int *argc,char ***argv)
if (user_supplied_post_statements)
(void)parse_delimiter(tmp_string, &post_statements,
delimiter[0]);
- my_free(tmp_string, MYF(0));
+ my_free(tmp_string);
}
else if (user_supplied_post_statements)
{
@@ -1563,9 +1578,9 @@ drop_primary_key_list(void)
if (primary_keys_number_of)
{
for (counter= 0; counter < primary_keys_number_of; counter++)
- my_free(primary_keys[counter], MYF(0));
+ my_free(primary_keys[counter]);
- my_free(primary_keys, MYF(0));
+ my_free(primary_keys);
}
return 0;
@@ -2167,11 +2182,9 @@ option_cleanup(option_string *stmt)
for (ptr= stmt; ptr; ptr= nptr)
{
nptr= ptr->next;
- if (ptr->string)
- my_free(ptr->string, MYF(0));
- if (ptr->option)
- my_free(ptr->option, MYF(0));
- my_free(ptr, MYF(0));
+ my_free(ptr->string);
+ my_free(ptr->option);
+ my_free(ptr);
}
}
@@ -2185,9 +2198,8 @@ statement_cleanup(statement *stmt)
for (ptr= stmt; ptr; ptr= nptr)
{
nptr= ptr->next;
- if (ptr->string)
- my_free(ptr->string, MYF(0));
- my_free(ptr, MYF(0));
+ my_free(ptr->string);
+ my_free(ptr);
}
}
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 89fcb56825e..22155005112 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -1,5 +1,4 @@
-/*
- Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
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
@@ -12,8 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
mysqltest
@@ -31,6 +29,7 @@
#include "client_priv.h"
#include <mysql_version.h>
#include <mysqld_error.h>
+#include <sql_common.h>
#include <m_ctype.h>
#include <my_dir.h>
#include <hash.h>
@@ -74,23 +73,28 @@
static int setenv(const char *name, const char *value, int overwrite);
#endif
+C_MODE_START
+static sig_handler signal_handler(int sig);
+static my_bool get_one_option(int optid, const struct my_option *,
+ char *argument);
+C_MODE_END
+
enum {
- OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION,
- OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
- OPT_MAX_CONNECT_RETRIES, OPT_MAX_CONNECTIONS,
- OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES
+ OPT_PS_PROTOCOL=OPT_MAX_CLIENT_OPTION, OPT_SP_PROTOCOL,
+ OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL, OPT_MAX_CONNECT_RETRIES,
+ OPT_MAX_CONNECTIONS, OPT_MARK_PROGRESS, OPT_LOG_DIR,
+ OPT_TAIL_LINES, OPT_RESULT_FORMAT_VERSION
};
static int record= 0, opt_sleep= -1;
static char *opt_db= 0, *opt_pass= 0;
const char *opt_user= 0, *opt_host= 0, *unix_sock= 0, *opt_basedir= "./";
-#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
-#endif
const char *opt_logdir= "";
const char *opt_include= 0, *opt_charsets_dir;
static int opt_port= 0;
static int opt_max_connect_retries;
+static int opt_result_format_version;
static int opt_max_connections= DEFAULT_MAX_CONN;
static my_bool opt_compress= 0, silent= 0, verbose= 0;
static my_bool debug_info_flag= 0, debug_check_flag= 0;
@@ -114,12 +118,49 @@ static char **default_argv;
static const char *load_default_groups[]= { "mysqltest", "client", 0 };
static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer;
+/* Info on properties that can be set with --enable_X and --disable_X */
+
+struct property {
+ my_bool *var; /* Actual variable */
+ my_bool set; /* Has been set for ONE command */
+ my_bool old; /* If set, thus is the old value */
+ my_bool reverse; /* Varible is true if disabled */
+ const char *env_name; /* Env. variable name */
+};
+
+static struct property prop_list[] = {
+ { &abort_on_error, 0, 1, 0, "$ENABLED_ABORT_ON_ERROR" },
+ { &disable_connect_log, 0, 1, 1, "$ENABLED_CONNECT_LOG" },
+ { &disable_info, 0, 1, 1, "$ENABLED_INFO" },
+ { &display_metadata, 0, 0, 0, "$ENABLED_METADATA" },
+ { &ps_protocol_enabled, 0, 0, 0, "$ENABLED_PS_PROTOCOL" },
+ { &disable_query_log, 0, 0, 1, "$ENABLED_QUERY_LOG" },
+ { &disable_result_log, 0, 0, 1, "$ENABLED_RESULT_LOG" },
+ { &disable_warnings, 0, 0, 1, "$ENABLED_WARNINGS" }
+};
+
+static my_bool once_property= FALSE;
+
+enum enum_prop {
+ P_ABORT= 0,
+ P_CONNECT,
+ P_INFO,
+ P_META,
+ P_PS,
+ P_QUERY,
+ P_RESULT,
+ P_WARN,
+ P_MAX
+};
+
static uint start_lineno= 0; /* Start line of current command */
static uint my_end_arg= 0;
/* Number of lines of the result to include in failure report */
static uint opt_tail_lines= 0;
+static uint opt_connect_timeout= 0;
+
static char delimiter[MAX_DELIMITER_LENGTH]= ";";
static uint delimiter_length= 1;
@@ -147,7 +188,7 @@ static struct st_block *cur_block, *block_stack_end;
struct st_test_file
{
FILE* file;
- const char *file_name;
+ char *file_name;
uint lineno; /* Current line in file */
};
@@ -181,6 +222,8 @@ static ulonglong timer_now(void);
static ulong connection_retry_sleep= 100000; /* Microseconds */
+static char *opt_plugin_dir= 0;
+
/* Precompiled re's */
static my_regex_t ps_re; /* the query can be run using PS protocol */
static my_regex_t sp_re; /* the query can be run as a SP */
@@ -218,8 +261,9 @@ typedef struct
int str_val_len;
int int_val;
int alloced_len;
- int int_dirty; /* do not update string if int is updated until first read */
- int alloced;
+ bool int_dirty; /* do not update string if int is updated until first read */
+ bool is_int;
+ bool alloced;
} VAR;
/*Perl/shell-like variable registers */
@@ -239,11 +283,14 @@ struct st_connection
my_bool pending;
#ifdef EMBEDDED_LIBRARY
+ pthread_t tid;
const char *cur_query;
int cur_query_len;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- pthread_t tid;
+ int command, result;
+ pthread_mutex_t query_mutex;
+ pthread_cond_t query_cond;
+ pthread_mutex_t result_mutex;
+ pthread_cond_t result_cond;
int query_done;
my_bool has_thread;
#endif /*EMBEDDED_LIBRARY*/
@@ -272,8 +319,7 @@ enum enum_commands {
Q_SEND, Q_REAP,
Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN,
Q_PING, Q_EVAL,
- Q_RPL_PROBE, Q_ENABLE_RPL_PARSE,
- Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT,
+ Q_EVAL_RESULT,
Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
Q_ENABLE_CONNECT_LOG, Q_DISABLE_CONNECT_LOG,
@@ -297,11 +343,12 @@ enum enum_commands {
Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR,
Q_LIST_FILES, Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE,
Q_SEND_SHUTDOWN, Q_SHUTDOWN_SERVER,
+ Q_RESULT_FORMAT_VERSION,
Q_MOVE_FILE, Q_REMOVE_FILES_WILDCARD, Q_SEND_EVAL,
-
Q_UNKNOWN, /* Unknown command. */
Q_COMMENT, /* Comments, ignored. */
- Q_COMMENT_WITH_COMMAND
+ Q_COMMENT_WITH_COMMAND,
+ Q_EMPTY_LINE
};
@@ -334,9 +381,6 @@ const char *command_names[]=
"replace_column",
"ping",
"eval",
- "rpl_probe",
- "enable_rpl_parse",
- "disable_rpl_parse",
"eval_result",
/* Enable/disable that the _query_ is logged to result file */
"enable_query_log",
@@ -397,6 +441,7 @@ const char *command_names[]=
"list_files_append_file",
"send_shutdown",
"shutdown_server",
+ "result_format",
"move_file",
"remove_files_wildcard",
"send_eval",
@@ -451,10 +496,37 @@ TYPELIB command_typelib= {array_elements(command_names),"",
command_names, 0};
DYNAMIC_STRING ds_res;
+/* Points to ds_warning in run_query, so it can be freed */
+DYNAMIC_STRING *ds_warn= 0;
struct st_command *curr_command= 0;
char builtin_echo[FN_REFLEN];
+struct st_replace_regex
+{
+DYNAMIC_ARRAY regex_arr; /* stores a list of st_regex subsitutions */
+
+/*
+Temporary storage areas for substitutions. To reduce unnessary copying
+and memory freeing/allocation, we pre-allocate two buffers, and alternate
+their use, one for input/one for output, the roles changing on the next
+st_regex substition. At the end of substitutions buf points to the
+one containing the final result.
+*/
+char* buf;
+char* even_buf;
+char* odd_buf;
+int even_buf_len;
+int odd_buf_len;
+};
+
+struct st_replace_regex *glob_replace_regex= 0;
+
+struct st_replace;
+struct st_replace *glob_replace= 0;
+void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds,
+const char *from, int len);
+
static void cleanup_and_exit(int exit_code) __attribute__((noreturn));
void die(const char *fmt, ...)
@@ -469,10 +541,10 @@ void log_msg(const char *fmt, ...)
VAR* var_from_env(const char *, const char *);
VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
int val_len);
-void var_free(void* v);
VAR* var_get(const char *var_name, const char** var_name_end,
my_bool raw, my_bool ignore_not_existing);
-void eval_expr(VAR* v, const char *p, const char** p_end, bool do_eval= true);
+void eval_expr(VAR* v, const char *p, const char** p_end,
+ bool open_end=false, bool do_eval=true);
my_bool match_delimiter(int c, const char *delim, uint length);
void dump_result_to_reject_file(char *buf, int size);
void dump_warning_messages();
@@ -483,6 +555,8 @@ void str_to_file(const char *fname, char *str, int size);
void str_to_file2(const char *fname, char *str, int size, my_bool append);
void fix_win_paths(const char *val, int len);
+const char *get_errname_from_code (uint error_code);
+int multi_reg_replace(struct st_replace_regex* r,char* val);
#ifdef __WIN__
void free_tmp_sh_file();
@@ -687,14 +761,6 @@ public:
LogFile log_file;
LogFile progress_file;
-
-/* Disable functions that only exist in MySQL 4.0 */
-#if MYSQL_VERSION_ID < 40000
-void mysql_enable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
-void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
-int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; }
-my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; }
-#endif
void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
int len);
void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
@@ -708,77 +774,150 @@ void handle_error(struct st_command*,
unsigned int err_errno, const char *err_error,
const char *err_sqlstate, DYNAMIC_STRING *ds);
void handle_no_error(struct st_command*);
+void revert_properties();
#ifdef EMBEDDED_LIBRARY
+#define EMB_SEND_QUERY 1
+#define EMB_READ_QUERY_RESULT 2
+#define EMB_END_CONNECTION 3
+
/* attributes of the query thread */
pthread_attr_t cn_thd_attrib;
+
/*
- send_one_query executes query in separate thread, which is
- necessary in embedded library to run 'send' in proper way.
- This implementation doesn't handle errors returned
- by mysql_send_query. It's technically possible, though
- I don't see where it is needed.
+ This procedure represents the connection and actually
+ runs queries when in the EMBEDDED-SERVER mode.
+ The run_query_normal() just sends request for running
+ mysql_send_query and mysql_read_query_result() here.
*/
-pthread_handler_t send_one_query(void *arg)
+
+pthread_handler_t connection_thread(void *arg)
{
struct st_connection *cn= (struct st_connection*)arg;
mysql_thread_init();
- VOID(mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len));
+ while (cn->command != EMB_END_CONNECTION)
+ {
+ if (!cn->command)
+ {
+ pthread_mutex_lock(&cn->query_mutex);
+ while (!cn->command)
+ pthread_cond_wait(&cn->query_cond, &cn->query_mutex);
+ pthread_mutex_unlock(&cn->query_mutex);
+ }
+ switch (cn->command)
+ {
+ case EMB_END_CONNECTION:
+ goto end_thread;
+ case EMB_SEND_QUERY:
+ cn->result= mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len);
+ break;
+ case EMB_READ_QUERY_RESULT:
+ cn->result= mysql_read_query_result(&cn->mysql);
+ break;
+ default:
+ DBUG_ASSERT(0);
+ }
+ cn->command= 0;
+ pthread_mutex_lock(&cn->result_mutex);
+ cn->query_done= 1;
+ pthread_cond_signal(&cn->result_cond);
+ pthread_mutex_unlock(&cn->result_mutex);
+ }
- mysql_thread_end();
- pthread_mutex_lock(&cn->mutex);
+end_thread:
cn->query_done= 1;
- VOID(pthread_cond_signal(&cn->cond));
- pthread_mutex_unlock(&cn->mutex);
+ mysql_thread_end();
pthread_exit(0);
return 0;
}
-static int do_send_query(struct st_connection *cn, const char *q, int q_len,
- int flags)
+static void wait_query_thread_done(struct st_connection *con)
{
- if (flags & QUERY_REAP_FLAG)
- return mysql_send_query(&cn->mysql, q, q_len);
+ DBUG_ASSERT(con->has_thread);
+ if (!con->query_done)
+ {
+ pthread_mutex_lock(&con->result_mutex);
+ while (!con->query_done)
+ pthread_cond_wait(&con->result_cond, &con->result_mutex);
+ pthread_mutex_unlock(&con->result_mutex);
+ }
+}
- if (pthread_mutex_init(&cn->mutex, NULL) ||
- pthread_cond_init(&cn->cond, NULL))
- die("Error in the thread library");
- cn->cur_query= q;
- cn->cur_query_len= q_len;
+static void signal_connection_thd(struct st_connection *cn, int command)
+{
+ DBUG_ASSERT(cn->has_thread);
cn->query_done= 0;
- if (pthread_create(&cn->tid, &cn_thd_attrib, send_one_query, (void*)cn))
- die("Cannot start new thread for query");
+ cn->command= command;
+ pthread_mutex_lock(&cn->query_mutex);
+ pthread_cond_signal(&cn->query_cond);
+ pthread_mutex_unlock(&cn->query_mutex);
+}
+
+
+/*
+ Sometimes we try to execute queries when the connection is closed.
+ It's done to make sure it was closed completely.
+ So that if our connection is closed (cn->has_thread == 0), we just return
+ the mysql_send_query() result which is an error in this case.
+*/
- cn->has_thread= TRUE;
+static int do_send_query(struct st_connection *cn, const char *q, int q_len)
+{
+ if (!cn->has_thread)
+ return mysql_send_query(&cn->mysql, q, q_len);
+ cn->cur_query= q;
+ cn->cur_query_len= q_len;
+ signal_connection_thd(cn, EMB_SEND_QUERY);
return 0;
}
-static void wait_query_thread_end(struct st_connection *con)
+static int do_read_query_result(struct st_connection *cn)
{
- if (!con->query_done)
- {
- pthread_mutex_lock(&con->mutex);
- while (!con->query_done)
- pthread_cond_wait(&con->cond, &con->mutex);
- pthread_mutex_unlock(&con->mutex);
- }
- if (con->has_thread)
- {
-#ifndef __WIN__
- /* May hang on Windows, but the problem it solves is not seen there */
- pthread_join(con->tid, NULL);
-#endif
- con->has_thread= FALSE;
- }
+ DBUG_ASSERT(cn->has_thread);
+ wait_query_thread_done(cn);
+ signal_connection_thd(cn, EMB_READ_QUERY_RESULT);
+ wait_query_thread_done(cn);
+
+ return cn->result;
+}
+
+
+static void emb_close_connection(struct st_connection *cn)
+{
+ if (!cn->has_thread)
+ return;
+ wait_query_thread_done(cn);
+ signal_connection_thd(cn, EMB_END_CONNECTION);
+ pthread_join(cn->tid, NULL);
+ cn->has_thread= FALSE;
+ pthread_mutex_destroy(&cn->query_mutex);
+ pthread_cond_destroy(&cn->query_cond);
+ pthread_mutex_destroy(&cn->result_mutex);
+ pthread_cond_destroy(&cn->result_cond);
+}
+
+
+static void init_connection_thd(struct st_connection *cn)
+{
+ cn->query_done= 1;
+ cn->command= 0;
+ if (pthread_mutex_init(&cn->query_mutex, NULL) ||
+ pthread_cond_init(&cn->query_cond, NULL) ||
+ pthread_mutex_init(&cn->result_mutex, NULL) ||
+ pthread_cond_init(&cn->result_cond, NULL) ||
+ pthread_create(&cn->tid, &cn_thd_attrib, connection_thread, (void*)cn))
+ die("Error in the thread library");
+ cn->has_thread=TRUE;
}
#else /*EMBEDDED_LIBRARY*/
-#define do_send_query(cn,q,q_len,flags) mysql_send_query(&cn->mysql, q, q_len)
+#define do_send_query(cn,q,q_len) mysql_send_query(&cn->mysql, q, q_len)
+#define do_read_query_result(cn) mysql_read_query_result(&cn->mysql)
#endif /*EMBEDDED_LIBRARY*/
@@ -1098,6 +1237,7 @@ void handle_command_error(struct st_command *command, uint error)
{
DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %d",
command->first_word_len, command->query, error));
+ revert_properties();
DBUG_VOID_RETURN;
}
if (command->expected_errors.count > 0)
@@ -1112,6 +1252,7 @@ void handle_command_error(struct st_command *command, uint error)
command->first_word_len, command->query,
command->expected_errors.err[0].code.errnum);
}
+ revert_properties();
DBUG_VOID_RETURN;
}
@@ -1121,15 +1262,18 @@ void close_connections()
DBUG_ENTER("close_connections");
for (--next_con; next_con >= connections; --next_con)
{
+#ifdef EMBEDDED_LIBRARY
+ emb_close_connection(next_con);
+#endif
if (next_con->stmt)
mysql_stmt_close(next_con->stmt);
next_con->stmt= 0;
mysql_close(&next_con->mysql);
if (next_con->util_mysql)
mysql_close(next_con->util_mysql);
- my_free(next_con->name, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(next_con->name);
}
- my_free(connections, MYF(MY_WME));
+ my_free(connections);
DBUG_VOID_RETURN;
}
@@ -1158,7 +1302,7 @@ void close_files()
DBUG_PRINT("info", ("closing file: %s", cur_file->file_name));
fclose(cur_file->file);
}
- my_free((uchar*) cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(cur_file->file_name);
cur_file->file_name= 0;
}
DBUG_VOID_RETURN;
@@ -1173,27 +1317,29 @@ void free_used_memory()
if (connections)
close_connections();
close_files();
- hash_free(&var_hash);
+ my_hash_free(&var_hash);
for (i= 0 ; i < q_lines.elements ; i++)
{
struct st_command **q= dynamic_element(&q_lines, i, struct st_command**);
- my_free((*q)->query_buf,MYF(MY_ALLOW_ZERO_PTR));
+ my_free((*q)->query_buf);
if ((*q)->content.str)
dynstr_free(&(*q)->content);
- my_free((*q),MYF(0));
+ my_free((*q));
}
for (i= 0; i < 10; i++)
{
if (var_reg[i].alloced_len)
- my_free(var_reg[i].str_val, MYF(MY_WME));
+ my_free(var_reg[i].str_val);
}
while (embedded_server_arg_count > 1)
- my_free(embedded_server_args[--embedded_server_arg_count],MYF(0));
+ my_free(embedded_server_args[--embedded_server_arg_count]);
delete_dynamic(&q_lines);
dynstr_free(&ds_res);
+ if (ds_warn)
+ dynstr_free(ds_warn);
free_all_replace();
- my_free(opt_pass,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_pass);
free_defaults(default_argv);
free_re();
#ifdef __WIN__
@@ -1206,7 +1352,6 @@ void free_used_memory()
mysql_server_end();
/* Don't use DBUG after mysql_server_end() */
- DBUG_VIOLATION_HELPER_LEAVE;
return;
}
@@ -1951,6 +2096,8 @@ static void strip_parentheses(struct st_command *command)
}
+C_MODE_START
+
static uchar *get_var_key(const uchar* var, size_t *len,
my_bool __attribute__((unused)) t)
{
@@ -1961,6 +2108,34 @@ static uchar *get_var_key(const uchar* var, size_t *len,
}
+static void var_free(void *v)
+{
+ VAR *var= (VAR*) v;
+ my_free(var->str_val);
+ if (var->alloced)
+ my_free(var);
+}
+
+C_MODE_END
+
+void var_check_int(VAR *v)
+{
+ char *endptr;
+ char *str= v->str_val;
+
+ /* Initially assume not a number */
+ v->int_val= 0;
+ v->is_int= false;
+ v->int_dirty= false;
+ if (!str) return;
+
+ v->int_val = (int) strtol(str, &endptr, 10);
+ /* It is an int if strtol consumed something up to end/space/tab */
+ if (endptr > str && (!*endptr || *endptr == ' ' || *endptr == '\t'))
+ v->is_int= true;
+}
+
+
VAR *var_init(VAR *v, const char *name, int name_len, const char *val,
int val_len)
{
@@ -1970,45 +2145,39 @@ VAR *var_init(VAR *v, const char *name, int name_len, const char *val,
name_len = strlen(name);
if (!val_len && val)
val_len = strlen(val) ;
+ if (!val)
+ val_len= 0;
val_alloc_len = val_len + 16; /* room to grow */
if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var)
+ name_len+2, MYF(MY_WME))))
die("Out of memory");
- tmp_var->name = (name) ? (char*) tmp_var + sizeof(*tmp_var) : 0;
+ if (name != NULL)
+ {
+ tmp_var->name= reinterpret_cast<char*>(tmp_var) + sizeof(*tmp_var);
+ memcpy(tmp_var->name, name, name_len);
+ tmp_var->name[name_len]= 0;
+ }
+ else
+ tmp_var->name= NULL;
+
tmp_var->alloced = (v == 0);
if (!(tmp_var->str_val = (char*)my_malloc(val_alloc_len+1, MYF(MY_WME))))
die("Out of memory");
- if (name)
- {
- memcpy(tmp_var->name, name, name_len);
- tmp_var->name[name_len]= 0;
- }
-
if (val)
- {
memcpy(tmp_var->str_val, val, val_len);
- tmp_var->str_val[val_len]= 0;
- }
+ tmp_var->str_val[val_len]= 0;
+
+ var_check_int(tmp_var);
tmp_var->name_len = name_len;
tmp_var->str_val_len = val_len;
tmp_var->alloced_len = val_alloc_len;
- tmp_var->int_val = (val) ? atoi(val) : 0;
- tmp_var->int_dirty = 0;
return tmp_var;
}
-void var_free(void *v)
-{
- my_free(((VAR*) v)->str_val, MYF(MY_WME));
- if (((VAR*)v)->alloced)
- my_free(v, MYF(MY_WME));
-}
-
-
VAR* var_from_env(const char *name, const char *def_val)
{
const char *tmp;
@@ -2050,8 +2219,8 @@ VAR* var_get(const char *var_name, const char **var_name_end, my_bool raw,
if (length >= MAX_VAR_NAME_LENGTH)
die("Too long variable name: %s", save_var_name);
- if (!(v = (VAR*) hash_search(&var_hash, (const uchar*) save_var_name,
- length)))
+ if (!(v = (VAR*) my_hash_search(&var_hash, (const uchar*) save_var_name,
+ length)))
{
char buff[MAX_VAR_NAME_LENGTH+1];
strmake(buff, save_var_name, length);
@@ -2065,7 +2234,7 @@ VAR* var_get(const char *var_name, const char **var_name_end, my_bool raw,
if (!raw && v->int_dirty)
{
sprintf(v->str_val, "%d", v->int_val);
- v->int_dirty = 0;
+ v->int_dirty= false;
v->str_val_len = strlen(v->str_val);
}
if (var_name_end)
@@ -2082,7 +2251,7 @@ err:
VAR *var_obtain(const char *name, int len)
{
VAR* v;
- if ((v = (VAR*)hash_search(&var_hash, (const uchar *) name, len)))
+ if ((v = (VAR*)my_hash_search(&var_hash, (const uchar *) name, len)))
return v;
v = var_init(0, name, len, "", 0);
my_hash_insert(&var_hash, (uchar*)v);
@@ -2127,7 +2296,7 @@ void var_set(const char *var_name, const char *var_name_end,
if (v->int_dirty)
{
sprintf(v->str_val, "%d", v->int_val);
- v->int_dirty= 0;
+ v->int_dirty=false;
v->str_val_len= strlen(v->str_val);
}
/* setenv() expects \0-terminated strings */
@@ -2160,6 +2329,51 @@ void var_set_int(const char* name, int value)
void var_set_errno(int sql_errno)
{
var_set_int("$mysql_errno", sql_errno);
+ var_set_string("$mysql_errname", get_errname_from_code(sql_errno));
+}
+
+/* Functions to handle --disable and --enable properties */
+
+void set_once_property(enum_prop prop, my_bool val)
+{
+ property &pr= prop_list[prop];
+ pr.set= 1;
+ pr.old= *pr.var;
+ *pr.var= val;
+ var_set_int(pr.env_name, (val != pr.reverse));
+ once_property= TRUE;
+}
+
+void set_property(st_command *command, enum_prop prop, my_bool val)
+{
+ char* p= command->first_argument;
+ if (p && !strcmp (p, "ONCE"))
+ {
+ command->last_argument= p + 4;
+ set_once_property(prop, val);
+ return;
+ }
+ property &pr= prop_list[prop];
+ *pr.var= val;
+ pr.set= 0;
+ var_set_int(pr.env_name, (val != pr.reverse));
+}
+
+void revert_properties()
+{
+ if (! once_property)
+ return;
+ for (int i= 0; i < (int) P_MAX; i++)
+ {
+ property &pr= prop_list[i];
+ if (pr.set)
+ {
+ *pr.var= pr.old;
+ pr.set= 0;
+ var_set_int(pr.env_name, (pr.old != pr.reverse));
+ }
+ }
+ once_property=FALSE;
}
@@ -2244,13 +2458,29 @@ void var_query_set(VAR *var, const char *query, const char** query_end)
if (row[i])
{
/* Add column to tab separated string */
- dynstr_append_mem(&result, row[i], lengths[i]);
+ char *val= row[i];
+ int len= lengths[i];
+
+ if (glob_replace_regex)
+ {
+ /* Regex replace */
+ if (!multi_reg_replace(glob_replace_regex, (char*)val))
+ {
+ val= glob_replace_regex->buf;
+ len= strlen(val);
+ }
+ }
+
+ if (glob_replace)
+ replace_strings_append(glob_replace, &result, val, len);
+ else
+ dynstr_append_mem(&result, val, len);
}
dynstr_append_mem(&result, "\t", 1);
}
end= result.str + result.length-1;
/* Evaluation should not recurse via backtick */
- eval_expr(var, result.str, (const char**) &end, false);
+ eval_expr(var, result.str, (const char**) &end, false, false);
dynstr_free(&result);
}
else
@@ -2261,6 +2491,59 @@ void var_query_set(VAR *var, const char *query, const char** query_end)
}
+static void
+set_result_format_version(ulong new_version)
+{
+ switch (new_version){
+ case 1:
+ /* The first format */
+ break;
+ case 2:
+ /* New format that also writes comments and empty lines
+ from test file to result */
+ break;
+ default:
+ die("Version format %lu has not yet been implemented", new_version);
+ break;
+ }
+ opt_result_format_version= new_version;
+}
+
+
+/*
+ Set the result format version to use when generating
+ the .result file
+*/
+
+static void
+do_result_format_version(struct st_command *command)
+{
+ long version;
+ static DYNAMIC_STRING ds_version;
+ const struct command_arg result_format_args[] = {
+ {"version", ARG_STRING, TRUE, &ds_version, "Version to use"}
+ };
+
+ DBUG_ENTER("do_result_format_version");
+
+ check_command_args(command, command->first_argument,
+ result_format_args,
+ sizeof(result_format_args)/sizeof(struct command_arg),
+ ',');
+
+ /* Convert version number to int */
+ if (!str2int(ds_version.str, 10, (long) 0, (long) INT_MAX, &version))
+ die("Invalid version number: '%s'", ds_version.str);
+
+ set_result_format_version(version);
+
+ dynstr_append(&ds_res, "result_format: ");
+ dynstr_append_mem(&ds_res, ds_version.str, ds_version.length);
+ dynstr_append(&ds_res, "\n");
+ dynstr_free(&ds_version);
+}
+
+
/*
Set variable from the result of a field in a query
@@ -2383,7 +2666,7 @@ void var_set_query_get_value(struct st_command *command, VAR *var)
break;
}
}
- eval_expr(var, value, 0, false);
+ eval_expr(var, value, 0, false, false);
}
dynstr_free(&ds_query);
mysql_free_result(res);
@@ -2395,6 +2678,7 @@ void var_set_query_get_value(struct st_command *command, VAR *var)
void var_copy(VAR *dest, VAR *src)
{
dest->int_val= src->int_val;
+ dest->is_int= src->is_int;
dest->int_dirty= src->int_dirty;
/* Alloc/realloc data for str_val in dest */
@@ -2413,7 +2697,8 @@ void var_copy(VAR *dest, VAR *src)
}
-void eval_expr(VAR *v, const char *p, const char **p_end, bool do_eval)
+void eval_expr(VAR *v, const char *p, const char **p_end,
+ bool open_end, bool do_eval)
{
DBUG_ENTER("eval_expr");
@@ -2435,7 +2720,7 @@ void eval_expr(VAR *v, const char *p, const char **p_end, bool do_eval)
/* Make sure there was just a $variable and nothing else */
const char* end= *p_end + 1;
- if (end < expected_end)
+ if (end < expected_end && !open_end)
die("Found junk '%.*s' after $variable in expression",
(int)(expected_end - end - 1), end);
@@ -2483,9 +2768,7 @@ void eval_expr(VAR *v, const char *p, const char **p_end, bool do_eval)
v->str_val_len = new_val_len;
memcpy(v->str_val, p, new_val_len);
v->str_val[new_val_len] = 0;
- v->int_val=atoi(p);
- DBUG_PRINT("info", ("atoi on '%s', returns: %d", p, v->int_val));
- v->int_dirty=0;
+ var_check_int(v);
}
DBUG_VOID_RETURN;
}
@@ -2832,6 +3115,8 @@ int do_modify_var(struct st_command *command,
die("The argument to %.*s must be a variable (start with $)",
command->first_word_len, command->query);
v= var_get(p, &p, 1, 0);
+ if (! v->is_int)
+ die("Cannot perform inc/dec on a non-numeric value");
switch (op) {
case DO_DEC:
v->int_val--;
@@ -2843,7 +3128,7 @@ int do_modify_var(struct st_command *command,
die("Invalid operator to do_modify_var");
break;
}
- v->int_dirty= 1;
+ v->int_dirty= true;
command->last_argument= (char*)++p;
return 0;
}
@@ -3101,8 +3386,9 @@ void do_copy_file(struct st_command *command)
' ');
DBUG_PRINT("info", ("Copy %s to %s", ds_from_file.str, ds_to_file.str));
+ /* MY_HOLD_ORIGINAL_MODES prevents attempts to chown the file */
error= (my_copy(ds_from_file.str, ds_to_file.str,
- MYF(MY_DONT_OVERWRITE_FILE)) != 0);
+ MYF(MY_DONT_OVERWRITE_FILE | MY_HOLD_ORIGINAL_MODES)) != 0);
handle_command_error(command, error);
dynstr_free(&ds_from_file);
dynstr_free(&ds_to_file);
@@ -3160,6 +3446,7 @@ void do_move_file(struct st_command *command)
void do_chmod_file(struct st_command *command)
{
long mode= 0;
+ int err_code;
static DYNAMIC_STRING ds_mode;
static DYNAMIC_STRING ds_file;
const struct command_arg chmod_file_args[] = {
@@ -3179,7 +3466,10 @@ void do_chmod_file(struct st_command *command)
die("You must write a 4 digit octal number for mode");
DBUG_PRINT("info", ("chmod %o %s", (uint)mode, ds_file.str));
- handle_command_error(command, chmod(ds_file.str, mode));
+ err_code= chmod(ds_file.str, mode);
+ if (err_code < 0)
+ err_code= 1;
+ handle_command_error(command, err_code);
dynstr_free(&ds_mode);
dynstr_free(&ds_file);
DBUG_VOID_RETURN;
@@ -3750,7 +4040,6 @@ void do_send_quit(struct st_command *command)
void do_change_user(struct st_command *command)
{
MYSQL *mysql = &cur_con->mysql;
- /* static keyword to make the NetWare compiler happy. */
static DYNAMIC_STRING ds_user, ds_passwd, ds_db;
const struct command_arg change_user_args[] = {
{ "user", ARG_STRING, FALSE, &ds_user, "User to connect as" },
@@ -3772,13 +4061,15 @@ void do_change_user(struct st_command *command)
}
if (!ds_user.length)
+ {
dynstr_set(&ds_user, mysql->user);
- if (!ds_passwd.length)
- dynstr_set(&ds_passwd, mysql->passwd);
+ if (!ds_passwd.length)
+ dynstr_set(&ds_passwd, mysql->passwd);
- if (!ds_db.length)
- dynstr_set(&ds_db, mysql->db);
+ if (!ds_db.length)
+ dynstr_set(&ds_db, mysql->db);
+ }
DBUG_PRINT("info",("connection: '%s' user: '%s' password: '%s' database: '%s'",
cur_con->name, ds_user.str, ds_passwd.str, ds_db.str));
@@ -4066,12 +4357,8 @@ int do_save_master_pos()
MYSQL_ROW row;
MYSQL *mysql = &cur_con->mysql;
const char *query;
- int rpl_parse;
DBUG_ENTER("do_save_master_pos");
- rpl_parse = mysql_rpl_parse_enabled(mysql);
- mysql_disable_rpl_parse(mysql);
-
#ifdef HAVE_NDB_BINLOG
/*
Wait for ndb binlog to be up-to-date with all changes
@@ -4112,7 +4399,7 @@ int do_save_master_pos()
const char latest_applied_binlog_epoch_str[]=
"latest_applied_binlog_epoch=";
if (count)
- sleep(1);
+ my_sleep(100*1000); /* 100ms */
if (mysql_query(mysql, query= "show engine ndb status"))
die("failed in '%s': %d %s", query,
mysql_errno(mysql), mysql_error(mysql));
@@ -4201,7 +4488,7 @@ int do_save_master_pos()
count++;
if (latest_handled_binlog_epoch >= start_epoch)
do_continue= 0;
- else if (count > 30)
+ else if (count > 300) /* 30s */
{
break;
}
@@ -4221,10 +4508,6 @@ int do_save_master_pos()
strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1);
master_pos.pos = strtoul(row[1], (char**) 0, 10);
mysql_free_result(res);
-
- if (rpl_parse)
- mysql_enable_rpl_parse(mysql);
-
DBUG_RETURN(0);
}
@@ -4283,33 +4566,11 @@ void do_let(struct st_command *command)
var_set(var_name, var_name_end, let_rhs_expr.str,
(let_rhs_expr.str + let_rhs_expr.length));
dynstr_free(&let_rhs_expr);
+ revert_properties();
DBUG_VOID_RETURN;
}
-int do_rpl_probe(struct st_command *command __attribute__((unused)))
-{
- DBUG_ENTER("do_rpl_probe");
- if (mysql_rpl_probe(&cur_con->mysql))
- die("Failed in mysql_rpl_probe(): '%s'", mysql_error(&cur_con->mysql));
- DBUG_RETURN(0);
-}
-
-
-int do_enable_rpl_parse(struct st_command *command __attribute__((unused)))
-{
- mysql_enable_rpl_parse(&cur_con->mysql);
- return 0;
-}
-
-
-int do_disable_rpl_parse(struct st_command *command __attribute__((unused)))
-{
- mysql_disable_rpl_parse(&cur_con->mysql);
- return 0;
-}
-
-
/*
Sleep the number of specified seconds
@@ -4552,18 +4813,19 @@ void do_shutdown_server(struct st_command *command)
}
-#if MYSQL_VERSION_ID >= 50000
-/* List of error names to error codes, available from 5.0 */
+/* List of error names to error codes */
typedef struct
{
const char *name;
uint code;
+ const char *text;
} st_error;
static st_error global_error_names[] =
{
+ { "<No error>", -1U, "" },
#include <mysqld_ername.h>
- { 0, 0 }
+ { 0, 0, 0 }
};
uint get_errcode_from_name(char *error_name, char *error_end)
@@ -4592,22 +4854,35 @@ uint get_errcode_from_name(char *error_name, char *error_end)
die("Unknown SQL error name '%s'", error_name);
DBUG_RETURN(0);
}
-#else
-uint get_errcode_from_name(char *error_name __attribute__((unused)),
- char *error_end __attribute__((unused)))
+
+const char *get_errname_from_code (uint error_code)
{
- abort_not_in_this_version();
- return 0; /* Never reached */
-}
-#endif
+ st_error *e= global_error_names;
+ DBUG_ENTER("get_errname_from_code");
+ DBUG_PRINT("enter", ("error_code: %d", error_code));
+ if (! error_code)
+ {
+ DBUG_RETURN("");
+ }
+ for (; e->name; e++)
+ {
+ if (e->code == error_code)
+ {
+ DBUG_RETURN(e->name);
+ }
+ }
+ /* Apparently, errors without known names may occur */
+ DBUG_RETURN("<Unknown>");
+}
void do_get_errcodes(struct st_command *command)
{
struct st_match_err *to= saved_expected_errors.err;
char *p= command->first_argument;
uint count= 0;
+ char *next;
DBUG_ENTER("do_get_errcodes");
@@ -4627,6 +4902,17 @@ void do_get_errcodes(struct st_command *command)
while (*end && *end != ',' && *end != ' ')
end++;
+ next=end;
+
+ /* code to handle variables passed to mysqltest */
+ if( *p == '$')
+ {
+ const char* fin;
+ VAR *var = var_get(p,&fin,0,0);
+ p=var->str_val;
+ end=p+var->str_val_len;
+ }
+
if (*p == 'S')
{
char *to_ptr= to->code.sqlstate;
@@ -4701,7 +4987,7 @@ void do_get_errcodes(struct st_command *command)
die("Too many errorcodes specified");
/* Set pointer to the end of the last error code */
- p= end;
+ p= next;
/* Find next ',' */
while (*p && *p != ',')
@@ -4909,7 +5195,7 @@ void do_close_connection(struct st_command *command)
we need to check if the query's thread was finished and probably wait
(embedded-server specific)
*/
- wait_query_thread_end(con);
+ emb_close_connection(con);
#endif /*EMBEDDED_LIBRARY*/
if (con->stmt)
mysql_stmt_close(con->stmt);
@@ -4922,7 +5208,7 @@ void do_close_connection(struct st_command *command)
con->util_mysql= 0;
con->pending= FALSE;
- my_free(con->name, MYF(0));
+ my_free(con->name);
/*
When the connection is closed set name to "-closed_connection-"
@@ -4948,6 +5234,7 @@ void do_close_connection(struct st_command *command)
dynstr_append_mem(ds, ";\n", 2);
}
+ dynstr_free(&ds_connection);
DBUG_VOID_RETURN;
}
@@ -5132,6 +5419,7 @@ do_handle_error:
var_set_errno(0);
handle_no_error(command);
+ revert_properties();
return 1; /* Connected */
}
@@ -5168,7 +5456,7 @@ void do_connect(struct st_command *command)
int con_port= opt_port;
char *con_options;
my_bool con_ssl= 0, con_compress= 0;
- my_bool con_pipe= 0, con_shm= 0;
+ my_bool con_pipe= 0, con_shm= 0, con_cleartext_enable= 0;
struct st_connection* con_slot;
static DYNAMIC_STRING ds_connection_name;
@@ -5179,6 +5467,7 @@ void do_connect(struct st_command *command)
static DYNAMIC_STRING ds_port;
static DYNAMIC_STRING ds_sock;
static DYNAMIC_STRING ds_options;
+ static DYNAMIC_STRING ds_default_auth;
#ifdef HAVE_SMEM
static DYNAMIC_STRING ds_shm;
#endif
@@ -5190,7 +5479,8 @@ void do_connect(struct st_command *command)
{ "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" }
+ { "options", ARG_STRING, FALSE, &ds_options, "Options to use while connecting" },
+ { "default_auth", ARG_STRING, FALSE, &ds_default_auth, "Default authentication to use" }
};
DBUG_ENTER("do_connect");
@@ -5256,6 +5546,8 @@ void do_connect(struct st_command *command)
con_pipe= 1;
else if (!strncmp(con_options, "SHM", 3))
con_shm= 1;
+ else if (!strncmp(con_options, "CLEARTEXT", 9))
+ con_cleartext_enable= 1;
else
die("Illegal option to connect: %.*s",
(int) (end - con_options), con_options);
@@ -5276,11 +5568,16 @@ void do_connect(struct st_command *command)
}
#ifdef EMBEDDED_LIBRARY
- con_slot->query_done= 1;
- con_slot->has_thread= FALSE;
-#endif
+ init_connection_thd(con_slot);
+#endif /*EMBEDDED_LIBRARY*/
+
if (!mysql_init(&con_slot->mysql))
die("Failed on mysql_init()");
+
+ if (opt_connect_timeout)
+ mysql_options(&con_slot->mysql, MYSQL_OPT_CONNECT_TIMEOUT,
+ (void *) &opt_connect_timeout);
+
if (opt_compress || con_compress)
mysql_options(&con_slot->mysql, MYSQL_OPT_COMPRESS, NullS);
mysql_options(&con_slot->mysql, MYSQL_OPT_LOCAL_INFILE, 0);
@@ -5290,14 +5587,14 @@ void do_connect(struct st_command *command)
mysql_options(&con_slot->mysql, MYSQL_SET_CHARSET_DIR,
opt_charsets_dir);
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
if (opt_use_ssl)
con_ssl= 1;
#endif
if (con_ssl)
{
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
mysql_ssl_set(&con_slot->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
#if MYSQL_VERSION_ID >= 50000
@@ -5341,6 +5638,16 @@ void do_connect(struct st_command *command)
if (ds_database.length == 0)
dynstr_set(&ds_database, opt_db);
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(&con_slot->mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (ds_default_auth.length)
+ mysql_options(&con_slot->mysql, MYSQL_DEFAULT_AUTH, ds_default_auth.str);
+
+
+ if (con_cleartext_enable)
+ mysql_options(&con_slot->mysql, MYSQL_ENABLE_CLEARTEXT_PLUGIN,
+ (char*) &con_cleartext_enable);
/* Special database to allow one to connect without a database name */
if (ds_database.length && !strcmp(ds_database.str,"*NO-ONE*"))
dynstr_set(&ds_database, "");
@@ -5369,6 +5676,7 @@ void do_connect(struct st_command *command)
dynstr_free(&ds_port);
dynstr_free(&ds_sock);
dynstr_free(&ds_options);
+ dynstr_free(&ds_default_auth);
#ifdef HAVE_SMEM
dynstr_free(&ds_shm);
#endif
@@ -5408,6 +5716,40 @@ int do_done(struct st_command *command)
return 0;
}
+/* Operands available in if or while conditions */
+
+enum block_op {
+ EQ_OP,
+ NE_OP,
+ GT_OP,
+ GE_OP,
+ LT_OP,
+ LE_OP,
+ ILLEG_OP
+};
+
+
+enum block_op find_operand(const char *start)
+{
+ char first= *start;
+ char next= *(start+1);
+
+ if (first == '=' && next == '=')
+ return EQ_OP;
+ if (first == '!' && next == '=')
+ return NE_OP;
+ if (first == '>' && next == '=')
+ return GE_OP;
+ if (first == '>')
+ return GT_OP;
+ if (first == '<' && next == '=')
+ return LE_OP;
+ if (first == '<')
+ return LT_OP;
+
+ return ILLEG_OP;
+}
+
/*
Process start of a "if" or "while" statement
@@ -5433,6 +5775,13 @@ int do_done(struct st_command *command)
A '!' can be used before the <expr> to indicate it should
be executed if it evaluates to zero.
+ <expr> can also be a simple comparison condition:
+
+ <variable> <op> <expr>
+
+ The left hand side must be a variable, the right hand side can be a
+ variable, number, string or `query`. Operands are ==, !=, <, <=, >, >=.
+ == and != can be used for strings, all can be used for numerical values.
*/
void do_block(enum block_cmd cmd, struct st_command* command)
@@ -5468,6 +5817,9 @@ void do_block(enum block_cmd cmd, struct st_command* command)
if (!expr_start++)
die("missing '(' in %s", cmd_name);
+ while (my_isspace(charset_info, *expr_start))
+ expr_start++;
+
/* Check for !<expr> */
if (*expr_start == '!')
{
@@ -5488,14 +5840,110 @@ void do_block(enum block_cmd cmd, struct st_command* command)
die("Missing '{' after %s. Found \"%s\"", cmd_name, p);
var_init(&v,0,0,0,0);
- eval_expr(&v, expr_start, &expr_end);
+ /* If expression starts with a variable, it may be a compare condition */
+
+ if (*expr_start == '$')
+ {
+ const char *curr_ptr= expr_end;
+ eval_expr(&v, expr_start, &curr_ptr, true);
+ while (my_isspace(charset_info, *++curr_ptr))
+ {}
+ /* If there was nothing past the variable, skip condition part */
+ if (curr_ptr == expr_end)
+ goto NO_COMPARE;
+
+ enum block_op operand= find_operand(curr_ptr);
+ if (operand == ILLEG_OP)
+ die("Found junk '%.*s' after $variable in condition",
+ (int)(expr_end - curr_ptr), curr_ptr);
+
+ /* We could silently allow this, but may be confusing */
+ if (not_expr)
+ die("Negation and comparison should not be combined, please rewrite");
+
+ /* Skip the 1 or 2 chars of the operand, then white space */
+ if (operand == LT_OP || operand == GT_OP)
+ {
+ curr_ptr++;
+ }
+ else
+ {
+ curr_ptr+= 2;
+ }
+ while (my_isspace(charset_info, *curr_ptr))
+ curr_ptr++;
+ if (curr_ptr == expr_end)
+ die("Missing right operand in comparison");
+
+ /* Strip off trailing white space */
+ while (my_isspace(charset_info, expr_end[-1]))
+ expr_end--;
+ /* strip off ' or " around the string */
+ if (*curr_ptr == '\'' || *curr_ptr == '"')
+ {
+ if (expr_end[-1] != *curr_ptr)
+ die("Unterminated string value");
+ curr_ptr++;
+ expr_end--;
+ }
+ VAR v2;
+ var_init(&v2,0,0,0,0);
+ eval_expr(&v2, curr_ptr, &expr_end);
+
+ if ((operand!=EQ_OP && operand!=NE_OP) && ! (v.is_int && v2.is_int))
+ die ("Only == and != are supported for string values");
+
+ /* Now we overwrite the first variable with 0 or 1 (for false or true) */
+
+ switch (operand)
+ {
+ case EQ_OP:
+ if (v.is_int)
+ v.int_val= (v2.is_int && v2.int_val == v.int_val);
+ else
+ v.int_val= !strcmp (v.str_val, v2.str_val);
+ break;
+
+ case NE_OP:
+ if (v.is_int)
+ v.int_val= ! (v2.is_int && v2.int_val == v.int_val);
+ else
+ v.int_val= (strcmp (v.str_val, v2.str_val) != 0);
+ break;
+
+ case LT_OP:
+ v.int_val= (v.int_val < v2.int_val);
+ break;
+ case LE_OP:
+ v.int_val= (v.int_val <= v2.int_val);
+ break;
+ case GT_OP:
+ v.int_val= (v.int_val > v2.int_val);
+ break;
+ case GE_OP:
+ v.int_val= (v.int_val >= v2.int_val);
+ break;
+ case ILLEG_OP:
+ die("Impossible operator, this cannot happen");
+ }
+
+ v.is_int= TRUE;
+ var_free(&v2);
+ } else
+ {
+ if (*expr_start != '`' && ! my_isdigit(charset_info, *expr_start))
+ die("Expression in if/while must beging with $, ` or a number");
+ eval_expr(&v, expr_start, &expr_end);
+ }
+
+ NO_COMPARE:
/* Define inner block */
cur_block++;
cur_block->cmd= cmd;
- if (v.int_val)
+ if (v.is_int)
{
- cur_block->ok= TRUE;
+ cur_block->ok= (v.int_val != 0);
} else
/* Any non-empty string which does not begin with 0 is also TRUE */
{
@@ -5603,7 +6051,7 @@ my_bool end_of_query(int c)
int read_line(char *buf, int size)
{
- char c, UNINIT_VAR(last_quote);
+ char c, UNINIT_VAR(last_quote), last_char= 0;
char *p= buf, *buf_end= buf + size - 1;
int skip_char= 0;
my_bool have_slash= FALSE;
@@ -5626,7 +6074,7 @@ int read_line(char *buf, int size)
fclose(cur_file->file);
cur_file->file= 0;
}
- my_free((uchar*) cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(cur_file->file_name);
cur_file->file_name= 0;
if (cur_file == file_stack)
{
@@ -5707,14 +6155,24 @@ int read_line(char *buf, int size)
}
else if (my_isspace(charset_info, c))
{
- /* Skip all space at begining of line */
if (c == '\n')
{
+ if (last_char == '\n')
+ {
+ /* Two new lines in a row, return empty line */
+ DBUG_PRINT("info", ("Found two new lines in a row"));
+ *p++= c;
+ *p= 0;
+ DBUG_RETURN(0);
+ }
+
/* Query hasn't started yet */
start_lineno= cur_file->lineno;
DBUG_PRINT("info", ("Query hasn't started yet, start_lineno: %d",
start_lineno));
}
+
+ /* Skip all space at begining of line */
skip_char= 1;
}
else if (end_of_query(c))
@@ -5755,6 +6213,8 @@ int read_line(char *buf, int size)
}
+ last_char= c;
+
if (!skip_char)
{
/* Could be a multibyte character */
@@ -5964,9 +6424,10 @@ int read_command(struct st_command** command_ptr)
DBUG_RETURN(1);
}
- convert_to_format_v1(read_command_buf);
+ if (opt_result_format_version == 1)
+ convert_to_format_v1(read_command_buf);
- DBUG_PRINT("info", ("query: %s", read_command_buf));
+ DBUG_PRINT("info", ("query: '%s'", read_command_buf));
if (*p == '#')
{
command->type= Q_COMMENT;
@@ -5976,6 +6437,10 @@ int read_command(struct st_command** command_ptr)
command->type= Q_COMMENT_WITH_COMMAND;
p+= 2; /* Skip past -- */
}
+ else if (*p == '\n')
+ {
+ command->type= Q_EMPTY_LINE;
+ }
/* Skip leading spaces */
while (*p && my_isspace(charset_info, *p))
@@ -6076,21 +6541,21 @@ static struct my_option my_long_options[] =
{"result-file", 'R', "Read/store result from/in this file.",
&result_file_name, &result_file_name, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"result-format-version", OPT_RESULT_FORMAT_VERSION,
+ "Version of the result file format to use",
+ &opt_result_format_version,
+ &opt_result_format_version, 0,
+ GET_INT, REQUIRED_ARG, 1, 1, 2, 0, 0, 0},
{"server-arg", 'A', "Send option value to embedded server as a parameter.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"server-file", 'F', "Read embedded server arguments from file.",
0, 0, 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.", &shared_memory_base_name,
&shared_memory_base_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
0, 0, 0},
-#endif
{"silent", 's', "Suppress all normal output. Synonym for --quiet.",
&silent, &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
- "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG,
- 0, 0, 0, 0, 0, 0},
{"sleep", 'T', "Always sleep this many seconds on sleep commands.",
&opt_sleep, &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, -1, 0,
0, 0, 0},
@@ -6120,12 +6585,17 @@ static struct my_option my_long_options[] =
{"view-protocol", OPT_VIEW_PROTOCOL, "Use views for select.",
&view_protocol, &view_protocol, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"connect_timeout", OPT_CONNECT_TIMEOUT,
+ "Number of seconds before connection timeout.",
+ &opt_connect_timeout, &opt_connect_timeout, 0, GET_UINT, REQUIRED_ARG,
+ 120, 0, 3600 * 12, 0, 0, 0},
+ {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
+ &opt_plugin_dir, &opt_plugin_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
-#include <help_start.h>
-
void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,MTEST_VERSION,
@@ -6143,8 +6613,6 @@ void usage()
my_print_variables(my_long_options);
}
-#include <help_end.h>
-
/*
Read arguments for embedded server and put them into
@@ -6193,8 +6661,7 @@ void read_embedded_server_arguments(const char *name)
static my_bool
-get_one_option(int optid, const struct my_option *opt,
- char *argument)
+get_one_option(int optid, const struct my_option *opt, char *argument)
{
switch(optid) {
case '#':
@@ -6241,7 +6708,7 @@ get_one_option(int optid, const struct my_option *opt,
argument= (char*) ""; // Don't require password
if (argument)
{
- my_free(opt_pass, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_pass);
opt_pass= my_strdup(argument, MYF(MY_FAE));
while (*argument) *argument++= 'x'; /* Destroy argument */
tty_password= 0;
@@ -6274,10 +6741,8 @@ get_one_option(int optid, const struct my_option *opt,
case 'F':
read_embedded_server_arguments(argument);
break;
- case OPT_SKIP_SAFEMALLOC:
-#ifdef SAFEMALLOC
- sf_malloc_quick=1;
-#endif
+ case OPT_RESULT_FORMAT_VERSION:
+ set_result_format_version(opt_result_format_version);
break;
case 'V':
print_version();
@@ -6298,7 +6763,9 @@ get_one_option(int optid, const struct my_option *opt,
int parse_args(int argc, char **argv)
{
- load_defaults("my",load_default_groups,&argc,&argv);
+ if (load_defaults("my",load_default_groups,&argc,&argv))
+ exit(1);
+
default_argv= argv;
if ((handle_options(&argc, &argv, my_long_options, get_one_option)))
@@ -6412,6 +6879,8 @@ void init_win_path_patterns()
"$MYSQL_TMP_DIR",
"$MYSQLTEST_VARDIR",
"$MASTER_MYSOCK",
+ "$MYSQL_SHAREDIR",
+ "$MYSQL_LIBDIR",
"./test/" };
int num_paths= sizeof(paths)/sizeof(char*);
int i;
@@ -6436,7 +6905,7 @@ void init_win_path_patterns()
/* Don't insert zero length strings in patterns array */
if (strlen(p) == 0)
{
- my_free(p, MYF(0));
+ my_free(p);
continue;
}
@@ -6460,7 +6929,7 @@ void free_win_path_patterns()
for (i=0 ; i < patterns.elements ; i++)
{
const char** pattern= dynamic_element(&patterns, i, const char**);
- my_free((char*) *pattern, MYF(0));
+ my_free((void *) *pattern);
}
delete_dynamic(&patterns);
}
@@ -6653,12 +7122,12 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
for (i= 0; i < num_fields; i++)
{
/* Free data for output */
- my_free(my_bind[i].buffer, MYF(MY_WME | MY_FAE));
+ my_free(my_bind[i].buffer);
}
/* Free array with bind structs, lengths and NULL flags */
- my_free(my_bind , MYF(MY_WME | MY_FAE));
- my_free(length , MYF(MY_WME | MY_FAE));
- my_free(is_null , MYF(MY_WME | MY_FAE));
+ my_free(my_bind);
+ my_free(length);
+ my_free(is_null);
}
@@ -6819,21 +7288,13 @@ void run_query_normal(struct st_connection *cn, struct st_command *command,
/*
Send the query
*/
- if (do_send_query(cn, query, query_len, flags))
+ if (do_send_query(cn, query, query_len))
{
handle_error(command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds);
goto end;
}
}
-#ifdef EMBEDDED_LIBRARY
- /*
- Here we handle 'reap' command, so we need to check if the
- query's thread was finished and probably wait
- */
- else if (flags & QUERY_REAP_FLAG)
- wait_query_thread_end(cn);
-#endif /*EMBEDDED_LIBRARY*/
if (!(flags & QUERY_REAP_FLAG))
{
cn->pending= TRUE;
@@ -6846,7 +7307,7 @@ void run_query_normal(struct st_connection *cn, struct st_command *command,
When on first result set, call mysql_read_query_result to retrieve
answer to the query sent earlier
*/
- if ((counter==0) && mysql_read_query_result(mysql))
+ if ((counter==0) && do_read_query_result(cn))
{
/* we've failed to collect the result set */
cn->pending= TRUE;
@@ -6868,8 +7329,6 @@ void run_query_normal(struct st_connection *cn, struct st_command *command,
if (!disable_result_log)
{
- ulonglong UNINIT_VAR(affected_rows); /* Ok to be undef if 'disable_info' is set */
-
if (res)
{
MYSQL_FIELD *fields= mysql_fetch_fields(res);
@@ -6886,10 +7345,10 @@ void run_query_normal(struct st_connection *cn, struct st_command *command,
/*
Need to call mysql_affected_rows() before the "new"
- query to find the warnings
+ query to find the warnings.
*/
if (!disable_info)
- affected_rows= mysql_affected_rows(mysql);
+ append_info(ds, mysql_affected_rows(mysql), mysql_info(mysql));
/*
Add all warnings to the result. We can't do this if we are in
@@ -6904,9 +7363,6 @@ void run_query_normal(struct st_connection *cn, struct st_command *command,
dynstr_append_mem(ds, ds_warnings->str, ds_warnings->length);
}
}
-
- if (!disable_info)
- append_info(ds, affected_rows, mysql_info(mysql));
}
if (res)
@@ -6927,6 +7383,7 @@ void run_query_normal(struct st_connection *cn, struct st_command *command,
/* If we come here the query is both executed and read successfully */
handle_no_error(command);
+ revert_properties();
end:
@@ -7060,6 +7517,7 @@ void handle_error(struct st_command *command,
dynstr_append(ds,"Got one of the listed errors\n");
}
/* OK */
+ revert_properties();
DBUG_VOID_RETURN;
}
@@ -7087,6 +7545,7 @@ void handle_error(struct st_command *command,
command->expected_errors.err[0].code.sqlstate);
}
+ revert_properties();
DBUG_VOID_RETURN;
}
@@ -7120,7 +7579,6 @@ void handle_no_error(struct st_command *command)
die("query '%s' succeeded - should have failed with sqlstate %s...",
command->query, command->expected_errors.err[0].code.sqlstate);
}
-
DBUG_VOID_RETURN;
}
@@ -7285,40 +7743,34 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command,
}
/*
- Need to grab affected rows information before getting
- warnings here
+ Fetch info before fetching warnings, since it will be reset
+ otherwise.
*/
- {
- ulonglong UNINIT_VAR(affected_rows);
- if (!disable_info)
- affected_rows= mysql_affected_rows(mysql);
+ if (!disable_info)
+ append_info(ds, mysql_stmt_affected_rows(stmt), mysql_info(mysql));
- if (!disable_warnings)
- {
- /* Get the warnings from execute */
+ if (!disable_warnings)
+ {
+ /* Get the warnings from execute */
- /* Append warnings to ds - if there are any */
- if (append_warnings(&ds_execute_warnings, mysql) ||
- ds_execute_warnings.length ||
- ds_prepare_warnings.length ||
- ds_warnings->length)
- {
- dynstr_append_mem(ds, "Warnings:\n", 10);
- if (ds_warnings->length)
- dynstr_append_mem(ds, ds_warnings->str,
- ds_warnings->length);
- if (ds_prepare_warnings.length)
- dynstr_append_mem(ds, ds_prepare_warnings.str,
- ds_prepare_warnings.length);
- if (ds_execute_warnings.length)
- dynstr_append_mem(ds, ds_execute_warnings.str,
- ds_execute_warnings.length);
- }
+ /* Append warnings to ds - if there are any */
+ if (append_warnings(&ds_execute_warnings, mysql) ||
+ ds_execute_warnings.length ||
+ ds_prepare_warnings.length ||
+ ds_warnings->length)
+ {
+ dynstr_append_mem(ds, "Warnings:\n", 10);
+ if (ds_warnings->length)
+ dynstr_append_mem(ds, ds_warnings->str,
+ ds_warnings->length);
+ if (ds_prepare_warnings.length)
+ dynstr_append_mem(ds, ds_prepare_warnings.str,
+ ds_prepare_warnings.length);
+ if (ds_execute_warnings.length)
+ dynstr_append_mem(ds, ds_execute_warnings.str,
+ ds_execute_warnings.length);
}
-
- if (!disable_info)
- append_info(ds, affected_rows, mysql_info(mysql));
}
}
@@ -7328,7 +7780,7 @@ end:
dynstr_free(&ds_prepare_warnings);
dynstr_free(&ds_execute_warnings);
}
-
+ revert_properties();
/* Close the statement if - no reconnect, need new prepare */
if (mysql->reconnect)
@@ -7368,6 +7820,10 @@ int util_query(MYSQL* org_mysql, const char* query){
if (!(mysql= mysql_init(mysql)))
die("Failed in mysql_init()");
+ if (opt_connect_timeout)
+ mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT,
+ (void *) &opt_connect_timeout);
+
/* enable local infile, in non-binary builds often disabled by default */
mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, 0);
safe_connect(mysql, "util", org_mysql->host, org_mysql->user,
@@ -7377,7 +7833,7 @@ int util_query(MYSQL* org_mysql, const char* query){
cur_con->util_mysql= mysql;
}
- return mysql_query(mysql, query);
+ DBUG_RETURN(mysql_query(mysql, query));
}
@@ -7418,6 +7874,8 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
die ("Cannot reap on a connection without pending send");
init_dynamic_string(&ds_warnings, NULL, 0, 256);
+ ds_warn= &ds_warnings;
+
/*
Evaluate query if this is an eval command
*/
@@ -7575,7 +8033,8 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
ds, &ds_warnings);
dynstr_free(&ds_warnings);
- if (command->type == Q_EVAL)
+ ds_warn= 0;
+ if (command->type == Q_EVAL || command->type == Q_SEND_EVAL)
dynstr_free(&eval_query);
if (display_result_sorted)
@@ -7731,7 +8190,7 @@ void get_command_type(struct st_command* command)
save= command->query[command->first_word_len];
command->query[command->first_word_len]= 0;
- type= find_type(command->query, &command_typelib, 1+2);
+ type= find_type(command->query, &command_typelib, FIND_TYPE_NO_PREFIX);
command->query[command->first_word_len]= save;
if (type > 0)
{
@@ -7972,8 +8431,8 @@ int main(int argc, char **argv)
my_init_dynamic_array(&q_lines, sizeof(struct st_command*), 1024, 1024);
- if (hash_init(&var_hash, charset_info,
- 1024, 0, 0, get_var_key, var_free, MYF(0)))
+ if (my_hash_init(&var_hash, charset_info,
+ 1024, 0, 0, get_var_key, var_free, MYF(0)))
die("Variable hash initialization failed");
var_set_string("MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION);
@@ -8046,6 +8505,7 @@ int main(int argc, char **argv)
cur_file->file_name= my_strdup("<stdin>", MYF(MY_WME));
cur_file->lineno= 1;
}
+ var_set_string("MYSQLTEST_FILE", cur_file->file_name);
init_re();
/* Cursor protcol implies ps protocol */
@@ -8058,8 +8518,14 @@ int main(int argc, char **argv)
cursor_protocol_enabled= cursor_protocol;
st_connection *con= connections;
+#ifdef EMBEDDED_LIBRARY
+ init_connection_thd(con);
+#endif /*EMBEDDED_LIBRARY*/
if (!( mysql_init(&con->mysql)))
die("Failed in mysql_init()");
+ if (opt_connect_timeout)
+ mysql_options(&con->mysql, MYSQL_OPT_CONNECT_TIMEOUT,
+ (void *) &opt_connect_timeout);
if (opt_compress)
mysql_options(&con->mysql,MYSQL_OPT_COMPRESS,NullS);
mysql_options(&con->mysql, MYSQL_OPT_LOCAL_INFILE, 0);
@@ -8072,7 +8538,7 @@ int main(int argc, char **argv)
if (opt_protocol)
mysql_options(&con->mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
if (opt_use_ssl)
{
@@ -8174,64 +8640,47 @@ int main(int argc, char **argv)
case Q_DISCONNECT:
case Q_DIRTY_CLOSE:
do_close_connection(command); break;
- case Q_RPL_PROBE: do_rpl_probe(command); break;
- case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(command); break;
- case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(command); break;
case Q_ENABLE_QUERY_LOG:
- disable_query_log= 0;
- var_set_int("$ENABLED_QUERY_LOG", 1);
+ set_property(command, P_QUERY, 0);
break;
case Q_DISABLE_QUERY_LOG:
- disable_query_log= 1;
- var_set_int("$ENABLED_QUERY_LOG", 0);
+ set_property(command, P_QUERY, 1);
break;
case Q_ENABLE_ABORT_ON_ERROR:
- abort_on_error= 1;
- var_set_int("$ENABLED_ABORT_ON_ERROR", 1);
+ set_property(command, P_ABORT, 1);
break;
case Q_DISABLE_ABORT_ON_ERROR:
- abort_on_error= 0;
- var_set_int("$ENABLED_ABORT_ON_ERROR", 0);
+ set_property(command, P_ABORT, 0);
break;
case Q_ENABLE_RESULT_LOG:
- disable_result_log= 0;
- var_set_int("$ENABLED_RESULT_LOG", 1);
+ set_property(command, P_RESULT, 0);
break;
case Q_DISABLE_RESULT_LOG:
- disable_result_log=1;
- var_set_int("$ENABLED_RESULT_LOG", 0);
+ set_property(command, P_RESULT, 1);
break;
case Q_ENABLE_CONNECT_LOG:
- disable_connect_log=0;
- var_set_int("$ENABLED_CONNECT_LOG", 1);
+ set_property(command, P_CONNECT, 0);
break;
case Q_DISABLE_CONNECT_LOG:
- disable_connect_log=1;
- var_set_int("$ENABLED_CONNECT_LOG", 0);
+ set_property(command, P_CONNECT, 1);
break;
case Q_ENABLE_WARNINGS:
- disable_warnings= 0;
- var_set_int("$ENABLED_WARNINGS", 1);
+ set_property(command, P_WARN, 0);
break;
case Q_DISABLE_WARNINGS:
- disable_warnings= 1;
- var_set_int("$ENABLED_WARNINGS", 0);
+ set_property(command, P_WARN, 1);
break;
case Q_ENABLE_INFO:
- disable_info= 0;
- var_set_int("$ENABLED_INFO", 1);
+ set_property(command, P_INFO, 0);
break;
case Q_DISABLE_INFO:
- disable_info= 1;
- var_set_int("$ENABLED_INFO", 0);
+ set_property(command, P_INFO, 1);
break;
case Q_ENABLE_METADATA:
- display_metadata= 1;
- var_set_int("$ENABLED_METADATA", 1);
+ set_property(command, P_META, 1);
break;
case Q_DISABLE_METADATA:
- display_metadata= 0;
- var_set_int("$ENABLED_METADATA", 0);
+ set_property(command, P_META, 0);
break;
case Q_SOURCE: do_source(command); break;
case Q_SLEEP: do_sleep(command, 0); break;
@@ -8263,6 +8712,7 @@ int main(int argc, char **argv)
case Q_MOVE_FILE: do_move_file(command); break;
case Q_CHMOD_FILE: do_chmod_file(command); break;
case Q_PERL: do_perl(command); break;
+ case Q_RESULT_FORMAT_VERSION: do_result_format_version(command); break;
case Q_DELIMITER:
do_delimiter(command);
break;
@@ -8387,9 +8837,38 @@ int main(int argc, char **argv)
do_sync_with_master2(command, 0);
break;
}
- case Q_COMMENT: /* Ignore row */
+ case Q_COMMENT:
+ {
command->last_argument= command->end;
+
+ /* Don't output comments in v1 */
+ if (opt_result_format_version == 1)
+ break;
+
+ /* Don't output comments if query logging is off */
+ if (disable_query_log)
+ break;
+
+ /* Write comment's with two starting #'s to result file */
+ const char* p= command->query;
+ if (p && *p == '#' && *(p+1) == '#')
+ {
+ dynstr_append_mem(&ds_res, command->query, command->query_len);
+ dynstr_append(&ds_res, "\n");
+ }
break;
+ }
+ case Q_EMPTY_LINE:
+ /* Don't output newline in v1 */
+ if (opt_result_format_version == 1)
+ break;
+
+ /* Don't output newline if query logging is off */
+ if (disable_query_log)
+ break;
+
+ dynstr_append(&ds_res, "\n");
+ break;
case Q_PING:
handle_command_error(command, mysql_ping(&cur_con->mysql));
break;
@@ -8417,12 +8896,12 @@ int main(int argc, char **argv)
do_set_charset(command);
break;
case Q_DISABLE_PS_PROTOCOL:
- ps_protocol_enabled= 0;
+ set_property(command, P_PS, 0);
/* Close any open statements */
close_statements();
break;
case Q_ENABLE_PS_PROTOCOL:
- ps_protocol_enabled= ps_protocol;
+ set_property(command, P_PS, ps_protocol);
break;
case Q_DISABLE_RECONNECT:
set_reconnect(&cur_con->mysql, 0);
@@ -8651,11 +9130,11 @@ void do_get_replace_column(struct st_command *command)
if (!*from)
die("Wrong number of arguments to replace_column in '%s'", command->query);
to= get_string(&buff, &from, command);
- my_free(replace_column[column_number-1], MY_ALLOW_ZERO_PTR);
+ my_free(replace_column[column_number-1]);
replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE));
set_if_bigger(max_replace_column, column_number);
}
- my_free(start, MYF(0));
+ my_free(start);
command->last_argument= command->end;
DBUG_VOID_RETURN;
@@ -8669,7 +9148,7 @@ void free_replace_column()
{
if (replace_column[i])
{
- my_free(replace_column[i], 0);
+ my_free(replace_column[i]);
replace_column[i]= 0;
}
}
@@ -8687,20 +9166,15 @@ void free_replace_column()
typedef struct st_pointer_array { /* when using array-strings */
TYPELIB typelib; /* Pointer to strings */
uchar *str; /* Strings is here */
- int7 *flag; /* Flag about each var. */
+ uint8 *flag; /* Flag about each var. */
uint array_allocs,max_count,length,max_length;
} POINTER_ARRAY;
-struct st_replace;
struct st_replace *init_replace(char * *from, char * *to, uint count,
char * word_end_chars);
int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name);
-void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds,
- const char *from, int len);
void free_pointer_array(POINTER_ARRAY *pa);
-struct st_replace *glob_replace;
-
/*
Get arguments for replace. The syntax is:
replace from to [from to ...]
@@ -8750,7 +9224,7 @@ void do_get_replace(struct st_command *command)
die("Can't initialize replace from '%s'", command->query);
free_pointer_array(&from_array);
free_pointer_array(&to_array);
- my_free(start, MYF(0));
+ my_free(start);
command->last_argument= command->end;
DBUG_VOID_RETURN;
}
@@ -8759,11 +9233,8 @@ void do_get_replace(struct st_command *command)
void free_replace()
{
DBUG_ENTER("free_replace");
- if (glob_replace)
- {
- my_free(glob_replace,MYF(0));
- glob_replace=0;
- }
+ my_free(glob_replace);
+ glob_replace= NULL;
DBUG_VOID_RETURN;
}
@@ -8847,26 +9318,6 @@ struct st_regex
int icase; /* true if the match is case insensitive */
};
-struct st_replace_regex
-{
- DYNAMIC_ARRAY regex_arr; /* stores a list of st_regex subsitutions */
-
- /*
- Temporary storage areas for substitutions. To reduce unnessary copying
- and memory freeing/allocation, we pre-allocate two buffers, and alternate
- their use, one for input/one for output, the roles changing on the next
- st_regex substition. At the end of substitutions buf points to the
- one containing the final result.
- */
- char* buf;
- char* even_buf;
- char* odd_buf;
- int even_buf_len;
- int odd_buf_len;
-};
-
-struct st_replace_regex *glob_replace_regex= 0;
-
int reg_replace(char** buf_p, int* buf_len_p, char *pattern, char *replace,
char *string, int icase);
@@ -8983,7 +9434,7 @@ struct st_replace_regex* init_replace_regex(char* expr)
return res;
err:
- my_free(res,0);
+ my_free(res);
die("Error parsing replace_regex \"%s\"", expr);
return 0;
}
@@ -9065,7 +9516,13 @@ void do_get_replace_regex(struct st_command *command)
{
char *expr= command->first_argument;
free_replace_regex();
- if (!(glob_replace_regex=init_replace_regex(expr)))
+ /* Allow variable for the *entire* list of replacements */
+ if (*expr == '$')
+ {
+ VAR *val= var_get(expr, NULL, 0, 1);
+ expr= val ? val->str_val : NULL;
+ }
+ if (expr && *expr && !(glob_replace_regex=init_replace_regex(expr)))
die("Could not init replace_regex");
command->last_argument= command->end;
}
@@ -9075,9 +9532,9 @@ void free_replace_regex()
if (glob_replace_regex)
{
delete_dynamic(&glob_replace_regex->regex_arr);
- my_free(glob_replace_regex->even_buf,MYF(MY_ALLOW_ZERO_PTR));
- my_free(glob_replace_regex->odd_buf,MYF(MY_ALLOW_ZERO_PTR));
- my_free(glob_replace_regex,MYF(0));
+ my_free(glob_replace_regex->even_buf);
+ my_free(glob_replace_regex->odd_buf);
+ my_free(glob_replace_regex);
glob_replace_regex=0;
}
}
@@ -9272,7 +9729,7 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
str_p= str_end;
}
}
- my_free(subs, MYF(0));
+ my_free(subs);
my_regfree(&r);
*res_p= 0;
*buf_p= buf;
@@ -9396,7 +9853,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count,
free_sets(&sets);
DBUG_RETURN(0);
}
- VOID(make_new_set(&sets)); /* Set starting set */
+ (void) make_new_set(&sets); /* Set starting set */
make_sets_invisible(&sets); /* Hide previus sets */
used_sets=-1;
word_states=make_new_set(&sets); /* Start of new word */
@@ -9404,7 +9861,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count,
if (!(follow=(FOLLOWS*) my_malloc((states+2)*sizeof(FOLLOWS),MYF(MY_WME))))
{
free_sets(&sets);
- my_free(found_set,MYF(0));
+ my_free(found_set);
DBUG_RETURN(0);
}
@@ -9598,9 +10055,9 @@ REPLACE *init_replace(char * *from, char * *to,uint count,
replace[i].next[j]=(REPLACE*) (rep_str+(-sets.set[i].next[j]-1));
}
}
- my_free(follow,MYF(0));
+ my_free(follow);
free_sets(&sets);
- my_free(found_set,MYF(0));
+ my_free(found_set);
DBUG_PRINT("exit",("Replace table has %d states",sets.count));
DBUG_RETURN(replace);
}
@@ -9616,7 +10073,7 @@ int init_sets(REP_SETS *sets,uint states)
if (!(sets->bit_buffer=(uint*) my_malloc(sizeof(uint)*sets->size_of_bits*
SET_MALLOC_HUNC,MYF(MY_WME))))
{
- my_free(sets->set,MYF(0));
+ my_free(sets->set);
return 1;
}
return 0;
@@ -9677,8 +10134,8 @@ void free_last_set(REP_SETS *sets)
void free_sets(REP_SETS *sets)
{
- my_free(sets->set_buffer,MYF(0));
- my_free(sets->bit_buffer,MYF(0));
+ my_free(sets->set_buffer);
+ my_free(sets->bit_buffer);
return;
}
@@ -9816,12 +10273,12 @@ int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name)
if (!(pa->str= (uchar*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD),
MYF(MY_WME))))
{
- my_free((char*) pa->typelib.type_names,MYF(0));
+ my_free(pa->typelib.type_names);
DBUG_RETURN (-1);
}
pa->max_count=(PC_MALLOC-MALLOC_OVERHEAD)/(sizeof(uchar*)+
sizeof(*pa->flag));
- pa->flag= (int7*) (pa->typelib.type_names+pa->max_count);
+ pa->flag= (uint8*) (pa->typelib.type_names+pa->max_count);
pa->length=0;
pa->max_length=PS_MALLOC-MALLOC_OVERHEAD;
pa->array_allocs=1;
@@ -9857,14 +10314,14 @@ int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name)
pa->typelib.type_names=new_array;
old_count=pa->max_count;
pa->max_count=len/(sizeof(uchar*) + sizeof(*pa->flag));
- pa->flag= (int7*) (pa->typelib.type_names+pa->max_count);
+ pa->flag= (uint8*) (pa->typelib.type_names+pa->max_count);
memcpy((uchar*) pa->flag,(char *) (pa->typelib.type_names+old_count),
old_count*sizeof(*pa->flag));
}
pa->flag[pa->typelib.count]=0; /* Reset flag */
pa->typelib.type_names[pa->typelib.count++]= (char*) pa->str+pa->length;
pa->typelib.type_names[pa->typelib.count]= NullS; /* Put end-mark */
- VOID(strmov((char*) pa->str+pa->length,name));
+ (void) strmov((char*) pa->str+pa->length,name);
pa->length+=length;
DBUG_RETURN(0);
} /* insert_pointer_name */
@@ -9877,9 +10334,9 @@ void free_pointer_array(POINTER_ARRAY *pa)
if (pa->typelib.count)
{
pa->typelib.count=0;
- my_free((char*) pa->typelib.type_names,MYF(0));
+ my_free(pa->typelib.type_names);
pa->typelib.type_names=0;
- my_free(pa->str,MYF(0));
+ my_free(pa->str);
}
} /* free_pointer_array */
@@ -10013,14 +10470,14 @@ void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input)
#ifndef HAVE_SETENV
static int setenv(const char *name, const char *value, int overwrite)
{
- size_t buflen= strlen(name) + strlen(value) + 2;
- char *envvar= (char *)malloc(buflen);
- if(!envvar)
- return ENOMEM;
- strcpy(envvar, name);
- strcat(envvar, "=");
- strcat(envvar, value);
- putenv(envvar);
- return 0;
+ size_t buflen= strlen(name) + strlen(value) + 2;
+ char *envvar= (char *)malloc(buflen);
+ if(!envvar)
+ return ENOMEM;
+ strcpy(envvar, name);
+ strcat(envvar, "=");
+ strcat(envvar, value);
+ putenv(envvar);
+ return 0;
}
#endif
diff --git a/client/readline.cc b/client/readline.cc
index 7765a62766f..d850379353f 100644
--- a/client/readline.cc
+++ b/client/readline.cc
@@ -45,9 +45,9 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
if (!(line_buff=(LINE_BUFFER*)
my_malloc(sizeof(*line_buff),MYF(MY_WME | MY_ZEROFILL))))
return 0;
- if (init_line_buffer(line_buff,fileno(file),IO_SIZE,max_size))
+ if (init_line_buffer(line_buff,my_fileno(file),IO_SIZE,max_size))
{
- my_free(line_buff,MYF(0));
+ my_free(line_buff);
return 0;
}
return line_buff;
@@ -57,7 +57,7 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
char *batch_readline(LINE_BUFFER *line_buff)
{
char *pos;
- ulong out_length= 0;
+ ulong out_length;
if (!(pos=intern_read_line(line_buff, &out_length)))
return 0;
@@ -74,8 +74,8 @@ void batch_readline_end(LINE_BUFFER *line_buff)
{
if (line_buff)
{
- my_free(line_buff->buffer,MYF(MY_ALLOW_ZERO_PTR));
- my_free(line_buff,MYF(0));
+ my_free(line_buff->buffer);
+ my_free(line_buff);
}
}
@@ -88,7 +88,7 @@ LINE_BUFFER *batch_readline_command(LINE_BUFFER *line_buff, char * str)
return 0;
if (init_line_buffer_from_string(line_buff,str))
{
- my_free(line_buff,MYF(0));
+ my_free(line_buff);
return 0;
}
return line_buff;
diff --git a/client/sql_string.cc b/client/sql_string.cc
index 4a0f2df927b..0ad79ba5633 100644
--- a/client/sql_string.cc
+++ b/client/sql_string.cc
@@ -25,17 +25,7 @@
#include <my_sys.h>
#include <m_string.h>
#include <m_ctype.h>
-#ifdef HAVE_FCONVERT
-#include <floatingpoint.h>
-#endif
-
-/*
- The following extern declarations are ok as these are interface functions
- required by the string function
-*/
-
-extern void sql_alloc(size_t size);
-extern void sql_element_free(void *ptr);
+#include <mysql_com.h>
#include "sql_string.h"
@@ -43,9 +33,12 @@ extern void sql_element_free(void *ptr);
** String functions
*****************************************************************************/
-bool String::real_alloc(uint32 arg_length)
+bool String::real_alloc(uint32 length)
{
- arg_length=ALIGN_SIZE(arg_length+1);
+ uint32 arg_length= ALIGN_SIZE(length + 1);
+ DBUG_ASSERT(arg_length > length);
+ if (arg_length <= length)
+ return TRUE; /* Overflow */
str_length=0;
if (Alloced_length < arg_length)
{
@@ -68,6 +61,9 @@ bool String::real_alloc(uint32 arg_length)
bool String::realloc(uint32 alloc_length)
{
uint32 len=ALIGN_SIZE(alloc_length+1);
+ DBUG_ASSERT(len > alloc_length);
+ if (len <= alloc_length)
+ return TRUE; /* Overflow */
if (Alloced_length < len)
{
char *new_ptr;
@@ -120,84 +116,17 @@ bool String::set(double num,uint decimals, CHARSET_INFO *cs)
{
char buff[FLOATING_POINT_BUFFER];
uint dummy_errors;
+ size_t len;
str_charset=cs;
if (decimals >= NOT_FIXED_DEC)
{
- // Enough for a DATETIME
- uint32 len= sprintf(buff, "%.15g", num);
+ len= my_gcvt(num, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
return copy(buff, len, &my_charset_latin1, cs, &dummy_errors);
}
-#ifdef HAVE_FCONVERT
- int decpt,sign;
- char *pos,*to;
-
- VOID(fconvert(num,(int) decimals,&decpt,&sign,buff+1));
- if (!my_isdigit(&my_charset_latin1, buff[1]))
- { // Nan or Inf
- pos=buff+1;
- if (sign)
- {
- buff[0]='-';
- pos=buff;
- }
- uint dummy_errors;
- return copy(pos,(uint32) strlen(pos), &my_charset_latin1, cs, &dummy_errors);
- }
- if (alloc((uint32) ((uint32) decpt+3+decimals)))
- return TRUE;
- to=Ptr;
- if (sign)
- *to++='-';
-
- pos=buff+1;
- if (decpt < 0)
- { /* value is < 0 */
- *to++='0';
- if (!decimals)
- goto end;
- *to++='.';
- if ((uint32) -decpt > decimals)
- decpt= - (int) decimals;
- decimals=(uint32) ((int) decimals+decpt);
- while (decpt++ < 0)
- *to++='0';
- }
- else if (decpt == 0)
- {
- *to++= '0';
- if (!decimals)
- goto end;
- *to++='.';
- }
- else
- {
- while (decpt-- > 0)
- *to++= *pos++;
- if (!decimals)
- goto end;
- *to++='.';
- }
- while (decimals--)
- *to++= *pos++;
-
-end:
- *to=0;
- str_length=(uint32) (to-Ptr);
- return FALSE;
-#else
-#ifdef HAVE_SNPRINTF
- buff[sizeof(buff)-1]=0; // Safety
- IF_DBUG(int num_chars= )
- snprintf(buff, sizeof(buff)-1, "%.*f",(int) decimals, num);
- DBUG_ASSERT(num_chars > 0);
- DBUG_ASSERT(num_chars < (int) sizeof(buff));
-#else
- sprintf(buff,"%.*f",(int) decimals,num);
-#endif
- return copy(buff,(uint32) strlen(buff), &my_charset_latin1, cs,
+ len= my_fcvt(num, decimals, buff, NULL);
+ return copy(buff, (uint32) len, &my_charset_latin1, cs,
&dummy_errors);
-#endif
}
@@ -680,7 +609,8 @@ void String::qs_append(const char *str, uint32 len)
void String::qs_append(double d)
{
char *buff = Ptr + str_length;
- str_length+= sprintf(buff, buff, "%.15g", d);
+ str_length+= my_gcvt(d, MY_GCVT_ARG_DOUBLE, FLOATING_POINT_BUFFER - 1, buff,
+ NULL);
}
void String::qs_append(double *d)
diff --git a/client/sql_string.h b/client/sql_string.h
index 57d4d196e8c..0b92c370858 100644
--- a/client/sql_string.h
+++ b/client/sql_string.h
@@ -1,5 +1,7 @@
-/*
- Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+#ifndef CLIENT_SQL_STRING_INCLUDED
+#define CLIENT_SQL_STRING_INCLUDED
+
+/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
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
@@ -12,8 +14,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/* This file is originally from the mysql distribution. Coded by monty */
@@ -21,10 +22,6 @@
#pragma interface /* gcc class implementation */
#endif
-#ifndef NOT_FIXED_DEC
-#define NOT_FIXED_DEC 31
-#endif
-
class String;
int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
@@ -182,7 +179,7 @@ public:
{
alloced=0;
Alloced_length=0;
- my_free(Ptr,MYF(0));
+ my_free(Ptr);
Ptr=0;
str_length=0; /* Safety */
}
@@ -363,3 +360,5 @@ public:
return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length);
}
};
+
+#endif /* CLIENT_SQL_STRING_INCLUDED */