diff options
93 files changed, 1114 insertions, 483 deletions
diff --git a/.bzrignore b/.bzrignore index 329c5e227ca..fdcbc3b262b 100644 --- a/.bzrignore +++ b/.bzrignore @@ -2995,3 +2995,4 @@ win/vs71cache.txt win/vs8cache.txt zlib/*.ds? zlib/*.vcproj +support-files/mysqld_multi.server diff --git a/BUILD/compile-solaris-sparc-debug b/BUILD/compile-solaris-sparc-debug index 58fcecf5a71..43cabd644fa 100755 --- a/BUILD/compile-solaris-sparc-debug +++ b/BUILD/compile-solaris-sparc-debug @@ -6,6 +6,6 @@ make -k clean || true path=`dirname $0` . "$path/autorun.sh" -CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-debug +CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -O3 -fno-omit-frame-pointer" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-debug make -j 4 diff --git a/client/client_priv.h b/client/client_priv.h index 8bc8ef692de..97ff44b67fc 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -79,6 +79,6 @@ enum options_client OPT_SLAP_DETACH, OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT, OPT_SERVER_ID, OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT, - OPT_DEBUG_INFO, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE, OPT_WRITE_BINLOG, - OPT_MAX_CLIENT_OPTION + OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE, + OPT_WRITE_BINLOG, OPT_MAX_CLIENT_OPTION }; diff --git a/client/mysql.cc b/client/mysql.cc index fe057c8b8a4..c0423e0c897 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -43,7 +43,7 @@ #include <locale.h> #endif -const char *VER= "14.13"; +const char *VER= "14.14"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 @@ -129,7 +129,7 @@ enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT}; typedef enum enum_info_type INFO_TYPE; static MYSQL mysql; /* The connection */ -static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, +static my_bool ignore_errors=0,wait_flag=0,quick=0, connected=0,opt_raw_data=0,unbuffered=0,output_tables=0, opt_rehash=1,skip_updates=0,safe_updates=0,one_database=0, opt_compress=0, using_opt_local_infile=0, @@ -139,9 +139,11 @@ static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, default_charset_used= 0, opt_secure_auth= 0, default_pager_set= 0, opt_sigint_ignore= 0, show_warnings= 0, executing_query= 0, interrupted_query= 0; +static my_bool debug_info_flag, debug_check_flag; static my_bool column_types_flag; static ulong opt_max_allowed_packet, opt_net_buffer_length; static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0; +static 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, @@ -541,7 +543,7 @@ sig_handler mysql_end(int sig) my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR)); mysql_server_end(); free_defaults(defaults_argv); - my_end(info_flag ? MY_CHECK_ERROR : 0); + my_end(my_end_arg); exit(status.exit_status); } @@ -611,8 +613,11 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log", (uchar**) &default_dbug_option, (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-info", 'T', "Print some debug info at exit.", (uchar**) &info_flag, - (uchar**) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", 'T', "Print some debug info at exit.", (uchar**) &debug_info_flag, + (uchar**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"database", 'D', "Database to use.", (uchar**) ¤t_db, (uchar**) ¤t_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default-character-set", OPT_DEFAULT_CHARSET, @@ -927,7 +932,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case '#': DBUG_PUSH(argument ? argument : default_dbug_option); - info_flag= 1; + debug_info_flag= 1; break; case 's': if (argument == disabled_my_option) @@ -1021,6 +1026,10 @@ static int get_options(int argc, char **argv) } if (tty_password) opt_password= get_tty_password(NullS); + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; return(0); } @@ -3288,7 +3297,7 @@ sql_real_connect(char *host,char *database,char *user,char *password, } connected=1; #ifndef EMBEDDED_LIBRARY - mysql.reconnect=info_flag ? 1 : 0; // We want to know if this happens + mysql.reconnect= debug_info_flag; // We want to know if this happens #else mysql.reconnect= 1; #endif diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 504b4c95a8b..5da0235c913 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -17,6 +17,8 @@ #include <sslopt-vars.h> #include "../scripts/mysql_fix_privilege_tables_sql.c" +#define VER "1.1" + #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif @@ -32,7 +34,8 @@ static char mysql_path[FN_REFLEN]; static char mysqlcheck_path[FN_REFLEN]; -static my_bool opt_force, opt_verbose; +static my_bool opt_force, opt_verbose, debug_info_flag, debug_check_flag; +static uint my_end_arg= 0; static char *opt_user= (char*)"root"; static DYNAMIC_STRING ds_args; @@ -56,6 +59,11 @@ static struct my_option my_long_options[]= NO_ARG, 0, 0, 0, 0, 0, 0}, {"basedir", 'b', "Not used by mysql_upgrade. Only for backward compatibilty", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"character-sets-dir", OPT_CHARSETS_DIR, + "Directory where character sets are.", 0, + 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"compress", OPT_COMPRESS, "Use compression in server/client protocol.", + (uchar**)¬_used, (uchar**)¬_used, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"datadir", 'd', "Not used by mysql_upgrade. Only for backward compatibilty", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -66,14 +74,14 @@ static struct my_option my_long_options[]= {"debug", '#', "Output debug log", (uchar* *) & default_dbug_option, (uchar* *) & default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", 'T', "Print some debug info at exit.", (uchar**) &debug_info_flag, + (uchar**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"default-character-set", OPT_DEFAULT_CHARSET, "Set the default character set.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"character-sets-dir", OPT_CHARSETS_DIR, - "Directory where character sets are.", 0, - 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"compress", OPT_COMPRESS, "Use compression in server/client protocol.", - (uchar**)¬_used, (uchar**)¬_used, 0, GET_BOOL, NO_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.", (uchar**)&opt_force, (uchar**)&opt_force, 0, @@ -138,7 +146,7 @@ static void die(const char *fmt, ...) va_end(args); free_used_memory(); - my_end(MY_CHECK_ERROR); + my_end(my_end_arg); exit(1); } @@ -200,8 +208,9 @@ get_one_option(int optid, const struct my_option *opt, switch (optid) { case '?': - printf("MySQL utility for upgrading database to MySQL version %s\n", - MYSQL_SERVER_VERSION); + printf("%s Ver %s Distrib %s, for %s (%s)\n", + my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); + puts("MySQL utility for upgrading databases to new MySQL versions\n"); my_print_help(my_long_options); exit(0); break; @@ -209,6 +218,7 @@ get_one_option(int optid, const struct my_option *opt, case '#': DBUG_PUSH(argument ? argument : default_dbug_option); add_option= FALSE; + debug_check_flag= 1; break; case 'p': @@ -732,6 +742,10 @@ int main(int argc, char **argv) if (handle_options(&argc, &argv, my_long_options, get_one_option)) die(NULL); + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; if (tty_password) { @@ -780,7 +794,7 @@ int main(int argc, char **argv) create_mysql_upgrade_info_file(); free_used_memory(); - my_end(MY_CHECK_ERROR); + my_end(my_end_arg); exit(0); } diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index f6ff44c7d56..ce48ad03d33 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -40,9 +40,10 @@ ulonglong last_values[MAX_MYSQL_VAR]; static int interval=0; static my_bool option_force=0,interrupted=0,new_line=0, opt_compress=0, opt_relative=0, opt_verbose=0, opt_vertical=0, - tty_password= 0, info_flag= 0, opt_nobeep; -static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations, - opt_count_iterations= 0; + tty_password= 0, opt_nobeep; +static my_bool debug_info_flag= 0, debug_check_flag= 0; +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; #ifdef LATER_HAVE_NDBCLUSTER_DB @@ -134,10 +135,16 @@ static struct my_option my_long_options[] = "Number of iterations to make. This works with -i (--sleep) only.", (uchar**) &nr_iterations, (uchar**) &nr_iterations, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#ifndef DBUG_OFF {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (uchar**) &info_flag, - (uchar**) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, +#endif + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + (uchar**) &debug_info_flag, (uchar**) &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.", (uchar**) &option_force, (uchar**) &option_force, 0, GET_BOOL, NO_ARG, 0, 0, @@ -315,6 +322,10 @@ int main(int argc,char *argv[]) free_defaults(save_argv); exit(ho_error); } + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; if (argc == 0) { @@ -413,7 +424,7 @@ int main(int argc,char *argv[]) my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); #endif free_defaults(save_argv); - my_end(info_flag ? MY_CHECK_ERROR : 0); + my_end(my_end_arg); exit(error ? 1 : 0); return 0; } diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index edade347783..d8c4f4bbcbf 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -65,11 +65,13 @@ static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0; static bool opt_hexdump= 0; static bool opt_base64_output= 0; static const char* database= 0; -static my_bool force_opt= 0, short_form= 0, remote_opt= 0, info_flag; +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 int port= 0; +static uint my_end_arg; static const char* sock= 0; static const char* user = 0; static char* pass = 0; @@ -727,8 +729,12 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log.", (uchar**) &default_dbug_option, (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (uchar**) &info_flag, - (uchar**) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + (uchar**) &debug_info_flag, (uchar**) &debug_info_flag, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"disable-log-bin", 'D', "Disable binary log. This is useful, if you " "enabled --to-last-log and are sending the output to the same MySQL server. " "This way you could avoid an endless loop. You would also like to use it " @@ -860,7 +866,7 @@ static void die(const char* fmt, ...) va_end(args); cleanup(); /* We cannot free DBUG, it is used in global destructors after exit(). */ - my_end((info_flag ? MY_CHECK_ERROR : 0) | MY_DONT_FREE_DBUG); + my_end(my_end_arg | MY_DONT_FREE_DBUG); exit(1); } @@ -868,7 +874,7 @@ static void die(const char* fmt, ...) static void print_version() { - printf("%s Ver 3.2 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE); + printf("%s Ver 3.3 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE); NETWARE_SET_SCREEN_MODE(1); } @@ -984,7 +990,10 @@ static int parse_args(int *argc, char*** argv) load_defaults("my",load_default_groups,argc,argv); if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) exit(ho_error); - + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; return 0; } @@ -1597,7 +1606,7 @@ int main(int argc, char** argv) my_free_open_file_info(); load_processor.destroy(); /* We cannot free DBUG, it is used in global destructors after exit(). */ - my_end((info_flag ? MY_CHECK_ERROR : 0) | MY_DONT_FREE_DBUG); + my_end(my_end_arg | MY_DONT_FREE_DBUG); if (file_not_closed_error) { diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 372dfe860df..ee8d5c0d6d3 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -15,7 +15,7 @@ /* By Jani Tolonen, 2001-04-20, MySQL Development Team */ -#define CHECK_VERSION "2.4.5" +#define CHECK_VERSION "2.5.0" #include "client_priv.h" #include <m_ctype.h> @@ -33,10 +33,11 @@ static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0, opt_compress = 0, opt_databases = 0, opt_fast = 0, opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0, opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0, - tty_password= 0, opt_frm= 0, info_flag= 0, + tty_password= 0, opt_frm= 0, debug_info_flag= 0, debug_check_flag= 0, opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0, opt_write_binlog= 1; static uint verbose = 0, opt_mysql_port=0; +static int my_end_arg; static char * opt_mysql_unix_port = 0; static char *opt_password = 0, *current_user = 0, *default_charset = (char *)MYSQL_DEFAULT_CHARSET_NAME, @@ -96,8 +97,12 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (uchar**) &info_flag, - (uchar**) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + (uchar**) &debug_info_flag, (uchar**) &debug_info_flag, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"default-character-set", OPT_DEFAULT_CHARSET, "Set the default character set.", (uchar**) &default_charset, (uchar**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -305,6 +310,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case '#': DBUG_PUSH(argument ? argument : "d:t:o"); + debug_check_flag= 1; break; #include <sslopt-case.h> case OPT_TABLES: @@ -375,6 +381,10 @@ static int get_options(int *argc, char ***argv) } if (tty_password) opt_password = get_tty_password(NullS); + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; return(0); } /* get_options */ @@ -762,7 +772,7 @@ int main(int argc, char **argv) */ if (get_options(&argc, &argv)) { - my_end(info_flag ? MY_CHECK_ERROR : 0); + my_end(my_end_arg); exit(EX_USAGE); } if (dbConnect(current_host, current_user, opt_password)) @@ -804,6 +814,6 @@ int main(int argc, char **argv) #ifdef HAVE_SMEM my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); #endif - my_end(info_flag ? MY_CHECK_ERROR : 0); + my_end(my_end_arg); return(first_error!=0); } /* main */ diff --git a/client/mysqldump.c b/client/mysqldump.c index cfdde285040..bea360a1fb3 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -36,7 +36,7 @@ ** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov */ -#define DUMP_VERSION "10.12" +#define DUMP_VERSION "10.13" #include <my_global.h> #include <my_sys.h> @@ -100,9 +100,9 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1, opt_events= 0, opt_alltspcs=0, opt_notspcs= 0; +static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0; static ulong opt_max_allowed_packet, opt_net_buffer_length; static MYSQL mysql_connection,*mysql=0; -static my_bool insert_pat_inited= 0, info_flag; static DYNAMIC_STRING insert_pat; static char *opt_password=0,*current_user=0, *current_host=0,*path=0,*fields_terminated=0, @@ -116,7 +116,8 @@ static char compatible_mode_normal_str[255]; static ulong opt_compatible_mode= 0; #define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1 #define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2 -static uint opt_mysql_port= 0, opt_master_data; +static uint opt_mysql_port= 0, opt_master_data; +static uint my_end_arg; static char * opt_mysql_unix_port=0; static int first_error=0; static DYNAMIC_STRING extended_row; @@ -242,8 +243,12 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log", (uchar**) &default_dbug_option, (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (uchar**) &info_flag, - (uchar**) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + (uchar**) &debug_info_flag, (uchar**) &debug_info_flag, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"default-character-set", OPT_DEFAULT_CHARSET, "Set the default character set.", (uchar**) &default_charset, (uchar**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -724,7 +729,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case '#': DBUG_PUSH(argument ? argument : default_dbug_option); - info_flag= 1; + debug_check_flag= 1; break; #include <sslopt-case.h> case 'V': print_version(); exit(0); @@ -858,6 +863,10 @@ static int get_options(int *argc, char ***argv) *mysql_params->p_max_allowed_packet= opt_max_allowed_packet; *mysql_params->p_net_buffer_length= opt_net_buffer_length; + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; if (opt_delayed) opt_lock=0; /* Can't have lock with delayed */ @@ -1262,7 +1271,7 @@ static void free_resources() dynstr_free(&insert_pat); if (defaults_argv) free_defaults(defaults_argv); - my_end(info_flag ? MY_CHECK_ERROR : 0); + my_end(my_end_arg); } @@ -2061,7 +2070,6 @@ static uint get_table_structure(char *table, char *db, char *table_type, int len; MYSQL_RES *result; MYSQL_ROW row; - DBUG_ENTER("get_table_structure"); DBUG_PRINT("enter", ("db: %s table: %s", db, table)); @@ -2481,6 +2489,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, fprintf(sql_file, " (%s)",row[7]); /* Sub key */ check_io(sql_file); } + mysql_free_result(result); if (!opt_xml) { if (keynr) @@ -2822,7 +2831,7 @@ static void dump_table(char *table, char *db) /* The "table" could be a view. If so, we don't do anything here. */ - if (strcmp (table_type, "VIEW") == 0) + if (strcmp(table_type, "VIEW") == 0) DBUG_VOID_RETURN; /* Check --no-data flag */ @@ -2912,6 +2921,7 @@ static void dump_table(char *table, char *db) if (mysql_real_query(mysql, query_string.str, query_string.length)) { DB_error(mysql, "when executing 'SELECT INTO OUTFILE'"); + dynstr_free(&query_string); DBUG_VOID_RETURN; } } @@ -3266,8 +3276,8 @@ static void dump_table(char *table, char *db) check_io(md_result_file); } mysql_free_result(res); - dynstr_free(&query_string); } + dynstr_free(&query_string); DBUG_VOID_RETURN; err: @@ -3388,6 +3398,7 @@ static int dump_tablespaces(char* ts_where) char extra_format[]= "UNDO_BUFFER_SIZE="; char *ubs; char *endsemi; + DBUG_ENTER("dump_tablespaces"); init_dynamic_string_checked(&sqlbuf, "SELECT LOGFILE_GROUP_NAME," @@ -3419,6 +3430,7 @@ static int dump_tablespaces(char* ts_where) if (mysql_query(mysql, sqlbuf.str) || !(tableres = mysql_store_result(mysql))) { + dynstr_free(&sqlbuf); if (mysql_errno(mysql) == ER_BAD_TABLE_ERROR || mysql_errno(mysql) == ER_BAD_DB_ERROR || mysql_errno(mysql) == ER_UNKNOWN_TABLE) @@ -3427,12 +3439,12 @@ static int dump_tablespaces(char* ts_where) "\n--\n-- Not dumping tablespaces as no INFORMATION_SCHEMA.FILES" " table on this server\n--\n"); check_io(md_result_file); - return 0; + DBUG_RETURN(0); } - my_printf_error(0, "Error: Couldn't dump tablespaces %s", + my_printf_error(0, "Error: '%s' when trying to dump tablespaces", MYF(0), mysql_error(mysql)); - return 1; + DBUG_RETURN(1); } buf[0]= 0; @@ -3484,6 +3496,7 @@ static int dump_tablespaces(char* ts_where) } } dynstr_free(&sqlbuf); + mysql_free_result(tableres); init_dynamic_string_checked(&sqlbuf, "SELECT DISTINCT TABLESPACE_NAME," " FILE_NAME," @@ -3501,7 +3514,10 @@ static int dump_tablespaces(char* ts_where) dynstr_append_checked(&sqlbuf, " ORDER BY TABLESPACE_NAME, LOGFILE_GROUP_NAME"); if (mysql_query_with_error_report(mysql, &tableres, sqlbuf.str)) - return 1; + { + dynstr_free(&sqlbuf); + DBUG_RETURN(1); + } buf[0]= 0; while ((row= mysql_fetch_row(tableres))) @@ -3547,8 +3563,9 @@ static int dump_tablespaces(char* ts_where) } } + mysql_free_result(tableres); dynstr_free(&sqlbuf); - return 0; + DBUG_RETURN(0); } static int dump_all_databases() @@ -3635,8 +3652,11 @@ RETURN VALUES 0 Success. 1 Failure. */ + int init_dumping_tables(char *qdatabase) { + DBUG_ENTER("init_dumping_tables"); + if (!opt_create_db) { char qbuf[256]; @@ -3669,10 +3689,10 @@ int init_dumping_tables(char *qdatabase) { fprintf(md_result_file,"\n%s;\n",row[1]); } + mysql_free_result(dbinfo); } } - - return 0; + DBUG_RETURN(0); } /* init_dumping_tables */ @@ -3955,8 +3975,13 @@ static int dump_selected_tables(char *db, char **table_names, int tables) } else { - maybe_die(EX_ILLEGAL_TABLE, "Couldn't find table: \"%s\"", *table_names); - /* We shall countinue here, if --force was given */ + if (!ignore_errors) + { + dynstr_free(&lock_tables_query); + free_root(&root, MYF(0)); + } + maybe_die(EX_ILLEGAL_TABLE, "Couldn't find table: \"%s\"", *table_names); + /* We shall countinue here, if --force was given */ } } end= pos; @@ -3965,14 +3990,25 @@ static int dump_selected_tables(char *db, char **table_names, int tables) { if (mysql_real_query(mysql, lock_tables_query.str, lock_tables_query.length-1)) + { + if (!ignore_errors) + { + dynstr_free(&lock_tables_query); + free_root(&root, MYF(0)); + } DB_error(mysql, "when doing LOCK TABLES"); /* We shall countinue here, if --force was given */ + } } dynstr_free(&lock_tables_query); if (flush_logs) { if (mysql_refresh(mysql, REFRESH_LOG)) + { + if (!ignore_errors) + free_root(&root, MYF(0)); DB_error(mysql, "when doing refresh"); + } /* We shall countinue here, if --force was given */ } if (opt_xml) @@ -4535,6 +4571,9 @@ static my_bool get_view_structure(char *table, char* db) if (!(table_res= mysql_store_result(mysql)) || !(row= mysql_fetch_row(table_res))) { + if (table_res) + mysql_free_result(table_res); + dynstr_free(&ds_view); DB_error(mysql, "when trying to save the result of SHOW CREATE TABLE in ds_view."); DBUG_RETURN(1); } diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 396063731cf..afd9454d6be 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -24,7 +24,7 @@ ** * * ** ************************* */ -#define IMPORT_VERSION "3.6" +#define IMPORT_VERSION "3.7" #include "client_priv.h" #include "mysql_version.h" @@ -49,8 +49,8 @@ static char *add_load_option(char *ptr,const char *object, static my_bool verbose=0,lock_tables=0,ignore_errors=0,opt_delete=0, replace=0,silent=0,ignore=0,opt_compress=0, opt_low_priority= 0, tty_password= 0; -static my_bool info_flag= 0; -static uint opt_use_threads=0, opt_local_file=0; +static my_bool debug_info_flag= 0, debug_check_flag= 0; +static uint opt_use_threads=0, opt_local_file=0, my_end_arg= 0; static char *opt_password=0, *current_user=0, *current_host=0, *current_db=0, *fields_terminated=0, *lines_terminated=0, *enclosed=0, *opt_enclosed=0, @@ -87,8 +87,12 @@ static struct my_option my_long_options[] = 0, 0, 0}, {"debug",'#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (uchar**) &info_flag, - (uchar**) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + (uchar**) &debug_info_flag, (uchar**) &debug_info_flag, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"delete", 'd', "First delete all rows from table.", (uchar**) &opt_delete, (uchar**) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"fields-terminated-by", OPT_FTB, @@ -236,6 +240,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case '#': DBUG_PUSH(argument ? argument : "d:t:o"); + debug_check_flag= 1; break; #include <sslopt-case.h> case 'V': print_version(); exit(0); @@ -254,6 +259,10 @@ static int get_options(int *argc, char ***argv) if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) exit(ho_error); + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; if (enclosed && opt_enclosed) { @@ -659,6 +668,6 @@ int main(int argc, char **argv) my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); #endif free_defaults(argv_to_free); - my_end(info_flag ? MY_CHECK_ERROR : 0); + my_end(my_end_arg); return(exitcode); } diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 649658d6223..a7f6cadf450 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -15,7 +15,7 @@ /* Show databases, tables or columns */ -#define SHOW_VERSION "9.6" +#define SHOW_VERSION "9.10" #include "client_priv.h" #include <my_sys.h> @@ -28,7 +28,9 @@ static char * host=0, *opt_password=0, *user=0; static my_bool opt_show_keys= 0, opt_compress= 0, opt_count=0, opt_status= 0; -static my_bool tty_password= 0, opt_table_type= 0, info_flag= 0; +static 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; @@ -150,7 +152,7 @@ int main(int argc, char **argv) #ifdef HAVE_SMEM my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); #endif - my_end(info_flag ? MY_CHECK_ERROR : 0); + my_end(my_end_arg); exit(error ? 1 : 0); return 0; /* No compiler warnings */ } @@ -176,8 +178,12 @@ static struct my_option my_long_options[] = 0, 0, 0}, {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (uchar**) &info_flag, - (uchar**) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + (uchar**) &debug_info_flag, (uchar**) &debug_info_flag, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", (uchar**) &host, (uchar**) &host, 0, GET_STR, @@ -293,6 +299,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case '#': DBUG_PUSH(argument ? argument : "d:t:o"); + debug_check_flag= 1; break; #include <sslopt-case.h> case 'V': @@ -326,6 +333,10 @@ get_options(int *argc,char ***argv) */ opt_verbose= 2; } + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; return; } diff --git a/client/mysqlslap.c b/client/mysqlslap.c index aa15141bfdc..a550dcae260 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -69,7 +69,7 @@ TODO: */ -#define SHOW_VERSION "0.9" +#define SLAP_VERSION "1.0" #define HUGE_STRING_LENGTH 8196 #define RAND_STRING_SIZE 126 @@ -131,10 +131,8 @@ const char *delimiter= "\n"; const char *create_schema_string= "mysqlslap"; -static my_bool opt_preserve; - +static my_bool opt_preserve= 0, debug_info_flag= 0, debug_check_flag= 0; static my_bool opt_only_print= FALSE; - static my_bool opt_compress= FALSE, tty_password= FALSE, opt_silent= FALSE, auto_generate_sql_autoincrement= FALSE, @@ -149,13 +147,14 @@ static uint commit_rate; static uint detach_rate; const char *num_int_cols_opt; const char *num_char_cols_opt; + /* Yes, we do set defaults here */ static unsigned int num_int_cols= 1; static unsigned int num_char_cols= 1; static unsigned int num_int_cols_index= 0; static unsigned int num_char_cols_index= 0; - static unsigned int iterations; +static uint my_end_arg= 0; static char *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME; static ulonglong actual_queries= 0; static ulonglong auto_actual_queries; @@ -410,7 +409,7 @@ int main(int argc, char **argv) my_free(shared_memory_base_name, MYF(MY_ALLOW_ZERO_PTR)); #endif free_defaults(defaults_argv); - my_end(0); + my_end(my_end_arg); return 0; } @@ -569,6 +568,11 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", (uchar**) &default_dbug_option, (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", 'T', "Print some debug info at exit.", (uchar**) &debug_info_flag, + (uchar**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"delimiter", 'F', "Delimiter to use in SQL statements supplied in file or command line.", (uchar**) &delimiter, (uchar**) &delimiter, 0, GET_STR, REQUIRED_ARG, @@ -672,7 +676,7 @@ static struct my_option my_long_options[] = static void print_version(void) { - printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,SHOW_VERSION, + printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname, SLAP_VERSION, MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE); } @@ -731,6 +735,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case '#': DBUG_PUSH(argument ? argument : default_dbug_option); + debug_check_flag= 1; break; #include <sslopt-case.h> case 'V': @@ -1126,6 +1131,10 @@ get_options(int *argc,char ***argv) DBUG_ENTER("get_options"); if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option))) exit(ho_error); + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; if (!user) user= (char *)"root"; diff --git a/client/mysqltest.c b/client/mysqltest.c index e5b9a2eaf12..7ba57f7515c 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -31,7 +31,7 @@ Holyfoot */ -#define MTEST_VERSION "3.2" +#define MTEST_VERSION "3.3" #include "client_priv.h" #include <mysql_version.h> @@ -80,6 +80,7 @@ const char *opt_include= 0, *opt_charsets_dir; static int opt_port= 0; static int opt_max_connect_retries; static my_bool opt_compress= 0, silent= 0, verbose= 0; +static my_bool debug_info_flag= 0, debug_check_flag= 0; static my_bool tty_password= 0; static my_bool opt_mark_progress= 0; static my_bool ps_protocol= 0, ps_protocol_enabled= 0; @@ -100,6 +101,7 @@ static const char *load_default_groups[]= { "mysqltest", "client", 0 }; static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer; static uint start_lineno= 0; /* Start line of current command */ +static uint my_end_arg= 0; static char delimiter[MAX_DELIMITER_LENGTH]= ";"; static uint delimiter_length= 1; @@ -807,12 +809,10 @@ void free_used_memory() static void cleanup_and_exit(int exit_code) { free_used_memory(); - my_end(MY_CHECK_ERROR); + my_end(my_end_arg); - if (!silent) - { - switch (exit_code) - { + if (!silent) { + switch (exit_code) { case 1: printf("not ok\n"); break; @@ -1084,8 +1084,7 @@ void check_result(DYNAMIC_STRING* ds) DBUG_ENTER("check_result"); DBUG_ASSERT(result_file_name); - switch (dyn_string_cmp(ds, result_file_name)) - { + switch (dyn_string_cmp(ds, result_file_name)) { case RESULT_OK: break; /* ok */ case RESULT_LENGTH_MISMATCH: @@ -1929,7 +1928,10 @@ void do_exec(struct st_command *command) command->first_argument, ds_cmd.str)); if (!(res_file= my_popen(&ds_cmd, "r")) && command->abort_on_error) + { + dynstr_free(&ds_cmd); die("popen(\"%s\", \"r\") failed", command->first_argument); + } while (fgets(buf, sizeof(buf), res_file)) { @@ -1953,6 +1955,7 @@ void do_exec(struct st_command *command) { log_msg("exec of '%s failed, error: %d, status: %d, errno: %d", ds_cmd.str, error, status, errno); + dynstr_free(&ds_cmd); die("command \"%s\" failed", command->first_argument); } @@ -1971,8 +1974,11 @@ void do_exec(struct st_command *command) } } if (!ok) + { + dynstr_free(&ds_cmd); die("command \"%s\" failed with wrong error: %d", command->first_argument, status); + } } else if (command->expected_errors.err[0].type == ERR_ERRNO && command->expected_errors.err[0].code.errnum != 0) @@ -1980,6 +1986,7 @@ void do_exec(struct st_command *command) /* Error code we wanted was != 0, i.e. not an expected success */ log_msg("exec of '%s failed, error: %d, errno: %d", ds_cmd.str, error, errno); + dynstr_free(&ds_cmd); die("command \"%s\" succeeded - should have failed with errno %d...", command->first_argument, command->expected_errors.err[0].code.errnum); } @@ -4482,6 +4489,12 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif + {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + (uchar**) &debug_info_flag, (uchar**) &debug_info_flag, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", (uchar**) &opt_host, (uchar**) &opt_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"include", 'i', "Include SQL before each test case.", (uchar**) &opt_include, @@ -4625,6 +4638,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case '#': #ifndef DBUG_OFF DBUG_PUSH(argument ? argument : "d:t:S:i:O,/tmp/mysqltest.trace"); + debug_check_flag= 1; #endif break; case 'r': @@ -4724,6 +4738,10 @@ int parse_args(int argc, char **argv) opt_db= *argv; if (tty_password) opt_pass= get_tty_password(NullS); /* purify tested */ + if (debug_info_flag) + my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; + if (debug_check_flag) + my_end_arg= MY_CHECK_ERROR; return 0; } @@ -5377,11 +5395,8 @@ end: ds - dynamic string which is used for output buffer NOTE - If there is an unexpected error this function will abort mysqltest - immediately. - - RETURN VALUE - error - function will not return + If there is an unexpected error this function will abort mysqltest + immediately. */ void handle_error(struct st_command *command, diff --git a/configure.in b/configure.in index e2857cf43e3..23a926a5ce8 100644 --- a/configure.in +++ b/configure.in @@ -16,7 +16,7 @@ AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 DOT_FRM_VERSION=6 # See the libtool docs for information on how to do shared lib versions. -SHARED_LIB_MAJOR_VERSION=15 +SHARED_LIB_MAJOR_VERSION=16 SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0 NDB_SHARED_LIB_MAJOR_VERSION=3 NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0 @@ -1920,8 +1920,9 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bsearch bzero \ chsize cuserid fchmod fcntl \ fconvert fdatasync finite fpresetsticky fpsetmask fsync ftruncate \ getcwd gethostbyaddr_r gethostbyname_r getpass getpassphrase getpwnam \ - getpwuid getrlimit getrusage getwd gmtime_r index initgroups isnan \ - localtime_r locking longjmp lrand48 madvise mallinfo memcpy memmove \ + getpwuid getrlimit getrusage getwd index initgroups isnan \ + localtime_r gethrtime gmtime_r \ + locking longjmp lrand48 madvise mallinfo memcpy memmove \ mkstemp mlockall perror poll pread pthread_attr_create mmap mmap64 getpagesize \ pthread_attr_getstacksize pthread_attr_setprio pthread_attr_setschedparam \ pthread_attr_setstacksize pthread_condattr_create pthread_getsequence_np \ diff --git a/dbug/dbug.c b/dbug/dbug.c index 83c9ea37de1..9d638c299d3 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -1184,7 +1184,7 @@ void _db_dump_(uint _line_, const char *keyword, fprintf(cs->stack->out_file, "%s: ", cs->func); } sprintf(dbuff,"%s: Memory: 0x%lx Bytes: (%ld)\n", - keyword,(ulong) memory, length); + keyword, (ulong) memory, (long) length); (void) fputs(dbuff,cs->stack->out_file); pos=0; @@ -1449,6 +1449,7 @@ static void FreeState(CODE_STATE *cs, struct settings *state, int free_state) FreeList(state->p_functions); if (!is_shared(state, out_file)) DBUGCloseFile(cs, state->out_file); + (void) fflush(cs->stack->out_file); if (state->prof_file) DBUGCloseFile(cs, state->prof_file); if (free_state) @@ -1882,7 +1883,6 @@ static FILE *OpenProfile(CODE_STATE *cs, const char *name) { (void) fprintf(cs->stack->out_file, ERR_OPEN, cs->process, name); perror(""); - dbug_flush(0); (void) Delay(cs->stack->delay); } else @@ -1892,7 +1892,6 @@ static FILE *OpenProfile(CODE_STATE *cs, const char *name) { (void) fprintf(cs->stack->out_file, ERR_OPEN, cs->process, name); perror(""); - dbug_flush(0); } else { @@ -1931,7 +1930,7 @@ static void DBUGCloseFile(CODE_STATE *cs, FILE *fp) pthread_mutex_lock(&THR_LOCK_dbug); (void) fprintf(cs->stack->out_file, ERR_CLOSE, cs->process); perror(""); - dbug_flush(0); + dbug_flush(cs); } } diff --git a/include/heap.h b/include/heap.h index d309fb4f162..4a1c7d419ed 100644 --- a/include/heap.h +++ b/include/heap.h @@ -189,11 +189,14 @@ typedef struct st_heap_create_info ulonglong max_table_size; ulonglong auto_increment; my_bool with_auto_increment; + my_bool internal_table; } HP_CREATE_INFO; /* Prototypes for heap-functions */ extern HP_INFO *heap_open(const char *name, int mode); +extern HP_INFO *heap_open_from_share(HP_SHARE *share, int mode); +extern HP_INFO *heap_open_from_share_and_register(HP_SHARE *share, int mode); extern int heap_close(HP_INFO *info); extern int heap_write(HP_INFO *info,const uchar *buff); extern int heap_update(HP_INFO *info,const uchar *old,const uchar *newdata); @@ -204,7 +207,7 @@ extern int heap_delete(HP_INFO *info,const uchar *buff); extern int heap_info(HP_INFO *info,HEAPINFO *x,int flag); extern int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, uint reclength, ulong max_records, ulong min_records, - HP_CREATE_INFO *create_info); + HP_CREATE_INFO *create_info, HP_SHARE **share); extern int heap_delete_table(const char *name); extern void heap_drop_table(HP_INFO *info); extern int heap_extra(HP_INFO *info,enum ha_extra_function function); diff --git a/include/keycache.h b/include/keycache.h index 7f4ce86cea0..a6005bae878 100644 --- a/include/keycache.h +++ b/include/keycache.h @@ -47,7 +47,7 @@ typedef struct st_key_cache my_bool in_resize; /* true during resize operation */ my_bool resize_in_flush; /* true during flush of resize operation */ my_bool can_be_used; /* usage of cache for read/write is allowed */ - ulong key_cache_mem_size; /* specified size of the cache memory */ + size_t key_cache_mem_size; /* specified size of the cache memory */ uint key_cache_block_size; /* size of the page buffer of a cache block */ ulong min_warm_blocks; /* min number of warm blocks; */ ulong age_threshold; /* age threshold for hot blocks */ @@ -107,10 +107,10 @@ typedef struct st_key_cache extern KEY_CACHE dflt_key_cache_var, *dflt_key_cache; extern int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, - ulong use_mem, uint division_limit, + size_t use_mem, uint division_limit, uint age_threshold); extern int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, - ulong use_mem, uint division_limit, + size_t use_mem, uint division_limit, uint age_threshold); extern void change_key_cache_param(KEY_CACHE *keycache, uint division_limit, uint age_threshold); diff --git a/include/my_base.h b/include/my_base.h index 04127b81b78..339554979a8 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -48,6 +48,8 @@ #define HA_OPEN_FOR_REPAIR 32 /* open even if crashed */ #define HA_OPEN_FROM_SQL_LAYER 64 #define HA_OPEN_MMAP 128 /* open memory mapped */ +/* Internal temp table, used for temporary results */ +#define HA_OPEN_INTERNAL_TABLE 256 /* The following is parameter to ha_rkey() how to use key */ diff --git a/include/my_getopt.h b/include/my_getopt.h index 115abf00618..c74f3ed672e 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -31,6 +31,7 @@ C_MODE_START #define GET_DISABLED 11 #define GET_ENUM 12 #define GET_SET 13 +#define GET_DOUBLE 14 #define GET_ASK_ADDR 128 #define GET_TYPE_MASK 127 diff --git a/include/my_sys.h b/include/my_sys.h index fb949842e48..76c9a7f02c7 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -150,7 +150,7 @@ extern ulonglong sf_malloc_mem_limit; #else #define my_checkmalloc() #undef TERMINATE -#define TERMINATE(A) {} +#define TERMINATE(A,B) {} #define QUICK_SAFEMALLOC #define NORMAL_SAFEMALLOC extern void *my_malloc(size_t Size,myf MyFlags); @@ -618,7 +618,7 @@ extern int nt_share_delete(const char *name,myf MyFlags); #endif #ifndef TERMINATE -extern void TERMINATE(FILE *file); +extern void TERMINATE(FILE *file, uint flag); #endif extern void init_glob_errs(void); extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags); @@ -833,7 +833,7 @@ extern my_bool my_compress(uchar *, size_t *, size_t *); extern my_bool my_uncompress(uchar *, size_t , size_t *); extern uchar *my_compress_alloc(const uchar *packet, size_t *len, size_t *complen); -extern int packfrm(const uchar *, size_t, uchar **, size_t *); +extern int packfrm(uchar *, size_t, uchar **, size_t *); extern int unpackfrm(uchar **, size_t *, const uchar *); extern ha_checksum my_checksum(ha_checksum crc, const uchar *mem, @@ -846,7 +846,11 @@ extern void my_sleep(ulong m_seconds); extern uint my_set_max_open_files(uint files); void my_free_open_file_info(void); +extern time_t my_time(myf flags); extern ulonglong my_getsystime(void); +extern ulonglong my_micro_time(); +extern ulonglong my_micro_time_and_time(time_t *time_arg); +time_t my_time_possible_from_micro(ulonglong microtime); extern my_bool my_gethwaddr(uchar *to); extern int my_getncpus(); diff --git a/include/mysql.h b/include/mysql.h index 489813bc154..009f9c40947 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -109,6 +109,7 @@ typedef struct st_mysql_field { unsigned int decimals; /* Number of decimals in field */ unsigned int charsetnr; /* Character set */ enum enum_field_types type; /* Type of field. See mysql_com.h for types */ + void *extension; } MYSQL_FIELD; typedef char **MYSQL_ROW; /* return data as array of strings */ @@ -143,12 +144,13 @@ typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */ typedef struct embedded_query_result EMBEDDED_QUERY_RESULT; typedef struct st_mysql_data { - my_ulonglong rows; - unsigned int fields; MYSQL_ROWS *data; + struct embedded_query_result *embedded_info; MEM_ROOT alloc; + my_ulonglong rows; + unsigned int fields; /* extra info for embedded library */ - struct embedded_query_result *embedded_info; + void *extension; } MYSQL_DATA; enum mysql_option @@ -211,6 +213,7 @@ struct st_mysql_options { void (*local_infile_end)(void *); int (*local_infile_error)(void *, char *, unsigned int); void *local_infile_userdata; + void *extension; }; enum mysql_status @@ -300,27 +303,28 @@ typedef struct st_mysql from mysql_stmt_close if close had to cancel result set of this object. */ my_bool *unbuffered_fetch_owner; -#if defined(EMBEDDED_LIBRARY) || defined(EMBEDDED_LIBRARY_COMPATIBLE) || MYSQL_VERSION_ID >= 50100 /* needed for embedded server - no net buffer to store the 'info' */ char *info_buffer; -#endif + void *extension; } MYSQL; + typedef struct st_mysql_res { - my_ulonglong row_count; + my_ulonglong row_count; MYSQL_FIELD *fields; MYSQL_DATA *data; MYSQL_ROWS *data_cursor; unsigned long *lengths; /* column lengths of current row */ MYSQL *handle; /* for unbuffered reads */ - MEM_ROOT field_alloc; - unsigned int field_count, current_field; + const struct st_mysql_methods *methods; MYSQL_ROW row; /* If unbuffered read */ MYSQL_ROW current_row; /* buffer to current row */ + MEM_ROOT field_alloc; + unsigned int field_count, current_field; my_bool eof; /* Used by mysql_fetch_row */ /* mysql_stmt_close() had to cancel this result */ my_bool unbuffered_fetch_cancelled; - const struct st_mysql_methods *methods; + void *extension; } MYSQL_RES; #define MAX_MYSQL_MANAGER_ERR 256 @@ -340,21 +344,23 @@ typedef struct st_mysql_res { typedef struct st_mysql_manager { NET net; - char *host,*user,*passwd; + char *host, *user, *passwd; + char *net_buf, *net_buf_pos, *net_data_end; unsigned int port; - my_bool free_me; - my_bool eof; int cmd_status; int last_errno; - char* net_buf,*net_buf_pos,*net_data_end; int net_buf_size; + my_bool free_me; + my_bool eof; char last_error[MAX_MYSQL_MANAGER_ERR]; + void *extension; } MYSQL_MANAGER; typedef struct st_mysql_parameters { unsigned long *p_max_allowed_packet; unsigned long *p_net_buffer_length; + void *extension; } MYSQL_PARAMETERS; #if !defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) @@ -369,6 +375,7 @@ typedef struct st_mysql_parameters */ int STDCALL mysql_server_init(int argc, char **argv, char **groups); void STDCALL mysql_server_end(void); + /* mysql_server_init/end need to be called when using libmysqld or libmysqlclient (exactly, mysql_server_init() is called by mysql_init() so @@ -657,23 +664,24 @@ typedef struct st_mysql_bind void *buffer; /* buffer to get/put data */ /* set this if you want to track data truncations happened during fetch */ my_bool *error; - enum enum_field_types buffer_type; /* buffer type */ + unsigned char *row_ptr; /* for the current data position */ + void (*store_param_func)(NET *net, struct st_mysql_bind *param); + void (*fetch_result)(struct st_mysql_bind *, MYSQL_FIELD *, + unsigned char **row); + void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *, + unsigned char **row); /* output buffer length, must be set when fetching str/binary */ unsigned long buffer_length; - unsigned char *row_ptr; /* for the current data position */ unsigned long offset; /* offset position for char/binary fetch */ unsigned long length_value; /* Used if length is 0 */ unsigned int param_number; /* For null count and error messages */ unsigned int pack_length; /* Internal length for packed data */ + enum enum_field_types buffer_type; /* buffer type */ my_bool error_value; /* used if error is 0 */ my_bool is_unsigned; /* set if integer type is unsigned */ my_bool long_data_used; /* If used with mysql_send_long_data */ my_bool is_null_value; /* Used if is_null is 0 */ - void (*store_param_func)(NET *net, struct st_mysql_bind *param); - void (*fetch_result)(struct st_mysql_bind *, MYSQL_FIELD *, - unsigned char **row); - void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *, - unsigned char **row); + void *extension; } MYSQL_BIND; @@ -688,15 +696,15 @@ typedef struct st_mysql_stmt MYSQL_FIELD *fields; /* result set metadata */ MYSQL_DATA result; /* cached result set */ MYSQL_ROWS *data_cursor; /* current row in cached result */ - /* copy of mysql->affected_rows after statement execution */ - my_ulonglong affected_rows; - my_ulonglong insert_id; /* copy of mysql->insert_id */ /* mysql_stmt_fetch() calls this function to fetch one row (it's different for buffered, unbuffered and cursor fetch). */ int (*read_row_func)(struct st_mysql_stmt *stmt, unsigned char **row); + /* copy of mysql->affected_rows after statement execution */ + my_ulonglong affected_rows; + my_ulonglong insert_id; /* copy of mysql->insert_id */ unsigned long stmt_id; /* Id for prepared statement */ unsigned long flags; /* i.e. type of cursor to open */ unsigned long prefetch_rows; /* number of rows per one COM_FETCH */ @@ -722,6 +730,7 @@ typedef struct st_mysql_stmt metadata fields when doing mysql_stmt_store_result. */ my_bool update_max_length; + void *extension; } MYSQL_STMT; enum enum_stmt_attr_type diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index b87fcc60692..541fa7dfbe6 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -110,7 +110,7 @@ enum enum_mysql_show_type { SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG, SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, - SHOW_ARRAY, SHOW_FUNC + SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE }; struct st_mysql_show_var { diff --git a/include/mysql_com.h b/include/mysql_com.h index ae57e84a696..5850d48fbf5 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -186,25 +186,25 @@ typedef struct st_vio Vio; typedef struct st_net { #if !defined(CHECK_EMBEDDED_DIFFERENCES) || !defined(EMBEDDED_LIBRARY) - Vio* vio; + Vio *vio; unsigned char *buff,*buff_end,*write_pos,*read_pos; my_socket fd; /* For Perl DBI/dbd */ - unsigned long max_packet,max_packet_size; - unsigned int pkt_nr,compress_pkt_nr; - unsigned int write_timeout, read_timeout, retry_count; - int fcntl; - my_bool compress; /* The following variable is set if we are doing several queries in one command ( as in LOAD TABLE ... FROM MASTER ), and do not want to confuse the client with OK at the wrong time */ unsigned long remain_in_buf,length, buf_length, where_b; + unsigned long max_packet,max_packet_size; + unsigned int pkt_nr,compress_pkt_nr; + unsigned int write_timeout, read_timeout, retry_count; + int fcntl; unsigned int *return_status; unsigned char reading_or_writing; char save_char; my_bool no_send_ok; /* For SPs and other things that do multiple stmts */ my_bool no_send_eof; /* For SPs' first version read-only cursors */ + my_bool compress; /* Set if OK packet is already sent, and we do not need to send error messages @@ -215,20 +215,20 @@ typedef struct st_net { queries in cache that have not stored its results yet */ #endif - char last_error[MYSQL_ERRMSG_SIZE], sqlstate[SQLSTATE_LENGTH+1]; - unsigned int last_errno; - unsigned char error; - /* 'query_cache_query' should be accessed only via query cache functions and methods to maintain proper locking. */ unsigned char *query_cache_query; - + unsigned int last_errno; + unsigned char error; my_bool report_error; /* We should report error (we have unreported error) */ my_bool return_errno; + char last_error[MYSQL_ERRMSG_SIZE], sqlstate[SQLSTATE_LENGTH+1]; + void *extension; } NET; + #define packet_error (~(unsigned long) 0) enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY, @@ -389,6 +389,7 @@ typedef struct st_udf_args char *maybe_null; /* Set to 1 for all maybe_null args */ char **attributes; /* Pointer to attribute name */ unsigned long *attribute_lengths; /* Length of attribute arguments */ + void *extension; } UDF_ARGS; /* This holds information about the result */ @@ -399,7 +400,9 @@ typedef struct st_udf_init unsigned int decimals; /* for real functions */ unsigned long max_length; /* For string functions */ char *ptr; /* free pointer for function data */ - my_bool const_item; /* 0 if result is independent of arguments */ + /* 0 if result is independent of arguments */ + my_bool const_item; + void *extension; } UDF_INIT; /* Constants when using compression */ diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index 7d4dcc1e919..c1585e10e25 100644 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -63,7 +63,7 @@ ADD_LIBRARY(libmysql SHARED dll.c libmysql.def ../strings/strmov.c ../strings/strnlen.c ../strings/strnmov.c ../strings/strtod.c ../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c ../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c - ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c) + ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c ../mysys/my_getsystime.c) ADD_DEPENDENCIES(libmysql dbug vio mysys strings GenError zlib yassl taocrypt) TARGET_LINK_LIBRARIES(libmysql mysys strings wsock32) diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index c24c6ab52db..3a2559921f9 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -68,7 +68,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \ mf_iocache2.lo my_seek.lo my_sleep.lo \ my_pread.lo mf_cache.lo md5.lo sha1.lo \ my_getopt.lo my_gethostbyname.lo my_port.lo \ - my_rename.lo my_chsize.lo + my_rename.lo my_chsize.lo my_getsystime.lo sqlobjects = net.lo sql_cmn_objects = pack.lo client.lo my_time.lo diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 46d0c8f1037..b2f59ba2a5a 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -215,7 +215,7 @@ void STDCALL mysql_server_end() } static MYSQL_PARAMETERS mysql_internal_parameters= -{&max_allowed_packet, &net_buffer_length}; +{&max_allowed_packet, &net_buffer_length, 0}; MYSQL_PARAMETERS *STDCALL mysql_get_parameters(void) { diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 1effa7c878d..e05849eda16 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1662,7 +1662,7 @@ sub generate_cmdline_mysqldump ($) { my($mysqld) = @_; return mtr_native_path($exe_mysqldump) . - " --no-defaults -uroot --debug-info " . + " --no-defaults -uroot --debug-check " . "--port=$mysqld->{'port'} " . "--socket=$mysqld->{'path_sock'} --password="; } @@ -1915,7 +1915,7 @@ sub environment_setup () { # ---------------------------------------------------- my $cmdline_mysqlcheck= mtr_native_path($exe_mysqlcheck) . - " --no-defaults --debug-info -uroot " . + " --no-defaults --debug-check -uroot " . "--port=$master->[0]->{'port'} " . "--socket=$master->[0]->{'path_sock'} --password="; @@ -1967,7 +1967,7 @@ sub environment_setup () { # ---------------------------------------------------- my $cmdline_mysqlimport= mtr_native_path($exe_mysqlimport) . - " -uroot --debug-info " . + " -uroot --debug-check " . "--port=$master->[0]->{'port'} " . "--socket=$master->[0]->{'path_sock'} --password="; @@ -1984,7 +1984,7 @@ sub environment_setup () { # ---------------------------------------------------- my $cmdline_mysqlshow= mtr_native_path($exe_mysqlshow) . - " -uroot --debug-info " . + " -uroot --debug-check " . "--port=$master->[0]->{'port'} " . "--socket=$master->[0]->{'path_sock'} --password="; @@ -2000,7 +2000,7 @@ sub environment_setup () { # ---------------------------------------------------- my $cmdline_mysqlbinlog= mtr_native_path($exe_mysqlbinlog) . - " --no-defaults --disable-force-if-open --debug-info"; + " --no-defaults --disable-force-if-open --debug-check"; if ( !$opt_extern && $mysql_version_id >= 50000 ) { $cmdline_mysqlbinlog .=" --character-sets-dir=$path_charsetsdir"; @@ -2018,7 +2018,7 @@ sub environment_setup () { # ---------------------------------------------------- my $cmdline_mysql= mtr_native_path($exe_mysql) . - " --no-defaults --debug-info --host=localhost --user=root --password= " . + " --no-defaults --debug-check --host=localhost --user=root --password= " . "--port=$master->[0]->{'port'} " . "--socket=$master->[0]->{'path_sock'} ". "--character-sets-dir=$path_charsetsdir"; diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index ff43993cfdb..e6d09306fcb 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -444,7 +444,14 @@ set interactive_timeout=100; set join_buffer_size=100; set last_insert_id=1; set global local_infile=1; -set long_query_time=100; +set long_query_time=0.000001; +select @@long_query_time; +@@long_query_time +0.000001 +set long_query_time=100.000001; +select @@long_query_time; +@@long_query_time +100.000001 set low_priority_updates=1; set max_allowed_packet=100; set global max_binlog_cache_size=100; diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index efa2ce4a27c..8f55d83c3de 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -268,7 +268,10 @@ set interactive_timeout=100; set join_buffer_size=100; set last_insert_id=1; set global local_infile=1; -set long_query_time=100; +set long_query_time=0.000001; +select @@long_query_time; +set long_query_time=100.000001; +select @@long_query_time; set low_priority_updates=1; set max_allowed_packet=100; set global max_binlog_cache_size=100; diff --git a/mysys/charset.c b/mysys/charset.c index 1c81e480404..cc1a238f281 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -323,14 +323,14 @@ static int charset_initialized=0; static my_bool my_read_charset_file(const char *filename, myf myflags) { - char *buf; + uchar *buf; int fd; uint len, tmp_len; MY_STAT stat_info; if (!my_stat(filename, &stat_info, MYF(myflags)) || ((len= (uint)stat_info.st_size) > MY_MAX_ALLOWED_BUF) || - !(buf= (char *)my_malloc(len,myflags))) + !(buf= (uchar*) my_malloc(len,myflags))) return TRUE; if ((fd=my_open(filename,O_RDONLY,myflags)) < 0) @@ -340,7 +340,7 @@ static my_bool my_read_charset_file(const char *filename, myf myflags) if (tmp_len != len) goto error; - if (my_parse_charset_xml(buf,len,add_collation)) + if (my_parse_charset_xml((char*) buf,len,add_collation)) { #ifdef NOT_YET printf("ERROR at line %d pos %d '%s'\n", @@ -350,7 +350,7 @@ static my_bool my_read_charset_file(const char *filename, myf myflags) #endif } - my_free(buf, myflags); + my_free(buf, myflags); return FALSE; error: diff --git a/mysys/default_modify.c b/mysys/default_modify.c index b2a43f511b9..78f6105b071 100644 --- a/mysys/default_modify.c +++ b/mysys/default_modify.c @@ -218,7 +218,7 @@ int modify_defaults_file(const char *file_location, const char *option, if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0, MYF(MY_WME)) || my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) || - my_fwrite(cnf_file, file_buffer, (size_t) (dst_ptr - file_buffer), + my_fwrite(cnf_file, (uchar*) file_buffer, (size_t) (dst_ptr - file_buffer), MYF(MY_NABP))) goto err; } diff --git a/mysys/hash.c b/mysys/hash.c index 47ddc5aa97d..4532b06b533 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -137,7 +137,7 @@ void my_hash_reset(HASH *hash) DBUG_VOID_RETURN; } - /* some helper functions */ +/* some helper functions */ /* This function is char* instead of uchar* as HPUX11 compiler can't @@ -149,9 +149,9 @@ hash_key(const HASH *hash, const uchar *record, size_t *length, my_bool first) { if (hash->get_key) - return (*hash->get_key)(record,length,first); + return (char*) (*hash->get_key)(record,length,first); *length=hash->key_length; - return (uchar*) record+hash->key_offset; + return (char*) record+hash->key_offset; } /* Calculate pos according to keys */ @@ -313,12 +313,14 @@ my_bool my_hash_insert(HASH *info,const uchar *record) uchar *ptr_to_rec,*ptr_to_rec2; HASH_LINK *data,*empty,*gpos,*gpos2,*pos; - LINT_INIT(gpos); LINT_INIT(gpos2); - LINT_INIT(ptr_to_rec); LINT_INIT(ptr_to_rec2); + LINT_INIT(gpos); + LINT_INIT(gpos2); + LINT_INIT(ptr_to_rec); + LINT_INIT(ptr_to_rec2); if (HASH_UNIQUE & info->flags) { - char *key= (char*) hash_key(info, record, &idx, 1); + uchar *key= (uchar*) hash_key(info, record, &idx, 1); if (hash_search(info, key, idx)) return(TRUE); /* Duplicate entry */ } @@ -544,14 +546,16 @@ my_bool hash_update(HASH *hash, uchar *record, uchar *old_key, if (HASH_UNIQUE & hash->flags) { HASH_SEARCH_STATE state; - char *found, *new_key= hash_key(hash, record, &idx, 1); + uchar *found, *new_key= (uchar*) hash_key(hash, record, &idx, 1); if ((found= hash_first(hash, new_key, idx, &state))) + { do { - if (found != (char*) record) + if (found != record) DBUG_RETURN(1); /* Duplicate entry */ } while ((found= hash_next(hash, new_key, idx, &state))); + } } data=dynamic_element(&hash->array,0,HASH_LINK*); diff --git a/mysys/mf_getdate.c b/mysys/mf_getdate.c index 2f08027a477..3a8e1be6a0b 100644 --- a/mysys/mf_getdate.c +++ b/mysys/mf_getdate.c @@ -42,7 +42,7 @@ void get_date(register char * to, int flag, time_t date) struct tm tm_tmp; #endif - skr=date ? (time_t) date : time((time_t*) 0); + skr=date ? (time_t) date : my_time(0); #if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT) if (flag & GETDATE_GMT) localtime_r(&skr,&tm_tmp); diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c index 8a5b91661c4..87ea995f518 100644 --- a/mysys/mf_iocache2.c +++ b/mysys/mf_iocache2.c @@ -246,7 +246,7 @@ size_t my_b_gets(IO_CACHE *info, char *to, size_t max_length) for (;;) { - char *pos,*end; + uchar *pos, *end; if (length > max_length) length=max_length; for (pos=info->read_pos,end=pos+length ; pos < end ;) @@ -323,7 +323,7 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args) length= (size_t) (fmt - start); out_length+=length; - if (my_b_write(info, start, length)) + if (my_b_write(info, (const uchar*) start, length)) goto err; if (*fmt == '\0') /* End of format */ @@ -378,14 +378,14 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args) size_t length2 = strlen(par); /* TODO: implement minimum width and precision */ out_length+= length2; - if (my_b_write(info, par, length2)) + if (my_b_write(info, (uchar*) par, length2)) goto err; } else if (*fmt == 'b') /* Sized buffer parameter, only precision makes sense */ { char *par = va_arg(args, char *); out_length+= precision; - if (my_b_write(info, par, precision)) + if (my_b_write(info, (uchar*) par, precision)) goto err; } else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */ @@ -400,7 +400,7 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args) else length2= (size_t) (int10_to_str((long) (uint) iarg,buff,10)- buff); out_length+= length2; - if (my_b_write(info, buff, length2)) + if (my_b_write(info, (uchar*) buff, length2)) goto err; } else if ((*fmt == 'l' && fmt[1] == 'd') || fmt[1] == 'u') @@ -416,13 +416,13 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args) else length2= (size_t) (int10_to_str(iarg,buff,10)- buff); out_length+= length2; - if (my_b_write(info, buff, length2)) + if (my_b_write(info, (uchar*) buff, length2)) goto err; } else { /* %% or unknown code */ - if (my_b_write(info, backtrack, fmt-backtrack)) + if (my_b_write(info, (uchar*) backtrack, (size_t) (fmt-backtrack))) goto err; out_length+= fmt-backtrack; } diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 1fef8aac170..c81da9a469a 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -366,10 +366,11 @@ static inline uint next_power(uint value) */ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, - ulong use_mem, uint division_limit, + size_t use_mem, uint division_limit, uint age_threshold) { - uint blocks, hash_links, length; + ulong blocks, hash_links; + size_t length; int error; DBUG_ENTER("init_key_cache"); DBUG_ASSERT(key_cache_block_size >= 512); @@ -405,8 +406,8 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, DBUG_PRINT("info", ("key_cache_block_size: %u", key_cache_block_size)); - blocks= (uint) (use_mem / (sizeof(BLOCK_LINK) + 2 * sizeof(HASH_LINK) + - sizeof(HASH_LINK*) * 5/4 + key_cache_block_size)); + blocks= (ulong) (use_mem / (sizeof(BLOCK_LINK) + 2 * sizeof(HASH_LINK) + + sizeof(HASH_LINK*) * 5/4 + key_cache_block_size)); /* It doesn't make sense to have too few blocks (less than 8) */ if (blocks >= 8) { @@ -424,18 +425,18 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, ALIGN_SIZE(hash_links * sizeof(HASH_LINK)) + ALIGN_SIZE(sizeof(HASH_LINK*) * keycache->hash_entries))) + - ((ulong) blocks * keycache->key_cache_block_size) > use_mem) + ((size_t) blocks * keycache->key_cache_block_size) > use_mem) blocks--; /* Allocate memory for cache page buffers */ if ((keycache->block_mem= - my_large_malloc((ulong) blocks * keycache->key_cache_block_size, + my_large_malloc((size_t) blocks * keycache->key_cache_block_size, MYF(MY_WME)))) { /* Allocate memory for blocks, hash_links and hash entries; For each block 2 hash links are allocated */ - if ((keycache->block_root= (BLOCK_LINK*) my_malloc((uint) length, + if ((keycache->block_root= (BLOCK_LINK*) my_malloc(length, MYF(0)))) break; my_large_free(keycache->block_mem, MYF(0)); @@ -448,7 +449,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, } blocks= blocks / 4*3; } - keycache->blocks_unused= (ulong) blocks; + keycache->blocks_unused= blocks; keycache->disk_blocks= (int) blocks; keycache->hash_links= hash_links; keycache->hash_root= (HASH_LINK**) ((char*) keycache->block_root + @@ -556,7 +557,7 @@ err: */ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, - ulong use_mem, uint division_limit, + size_t use_mem, uint division_limit, uint age_threshold) { int blocks; diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c index 99c0c959d94..a31b9595c85 100644 --- a/mysys/mf_pack.c +++ b/mysys/mf_pack.c @@ -56,7 +56,7 @@ void pack_dirname(char * to, const char *from) (buff_length == d_length && !bcmp(buff,start,d_length))) && *start != FN_LIBCHAR && *start) { /* Put current dir before */ - bchange(to,d_length,buff,buff_length,strlen(to)+1); + bchange((uchar*) to, d_length, (uchar*) buff, buff_length, strlen(to)+1); } } @@ -328,7 +328,7 @@ size_t unpack_dirname(char * to, const char *from) if (buff+h_length < suffix) bmove(buff+h_length,suffix,length); else - bmove_upp(buff+h_length+length,suffix+length,length); + bmove_upp((uchar*) buff+h_length+length, (uchar*) suffix+length, length); bmove(buff,tilde_expansion,h_length); } } diff --git a/mysys/mf_path.c b/mysys/mf_path.c index 7baded9d715..73e73cb7f76 100644 --- a/mysys/mf_path.c +++ b/mysys/mf_path.c @@ -46,7 +46,7 @@ char * my_path(char * to, const char *progname, if (!test_if_hard_path(to)) { if (!my_getwd(curr_dir,FN_REFLEN,MYF(0))) - bchange(to,0,curr_dir, (uint) strlen(curr_dir), (uint) strlen(to)+1); + bchange((uchar*) to, 0, (uchar*) curr_dir, strlen(curr_dir), strlen(to)+1); } } else diff --git a/mysys/my_append.c b/mysys/my_append.c index ddd3c91e832..35881a959d5 100644 --- a/mysys/my_append.c +++ b/mysys/my_append.c @@ -27,21 +27,22 @@ struct utimbuf { }; #endif - /* Append a file to another */ - -int my_append(const char *from, const char *to, myf MyFlags) +/* + Append a file to another + NOTES + Don't set MY_FNABP or MY_NABP bits on when calling this function +*/ - /* Dont set MY_FNABP or MY_NABP bits on - when calling this funktion */ +int my_append(const char *from, const char *to, myf MyFlags) { uint Count; File from_file,to_file; - char buff[IO_SIZE]; + uchar buff[IO_SIZE]; DBUG_ENTER("my_append"); DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); - from_file=to_file= -1; + from_file= to_file= -1; if ((from_file=my_open(from,O_RDONLY,MyFlags)) >= 0) { diff --git a/mysys/my_compress.c b/mysys/my_compress.c index d495a1c1c6d..bc9f8317487 100644 --- a/mysys/my_compress.c +++ b/mysys/my_compress.c @@ -154,17 +154,20 @@ my_bool my_uncompress(uchar *packet, size_t len, size_t *complen) SYNOPSIS packfrm() - data Data reference to frm file data + data Data reference to frm file data. len Length of frm file data out:pack_data Reference to the pointer to the packed frm data out:pack_len Length of packed frm file data + NOTES + data is replaced with compressed content + RETURN VALUES 0 Success >0 Failure */ -int packfrm(const uchar *data, size_t len, +int packfrm(uchar *data, size_t len, uchar **pack_data, size_t *pack_len) { int error; @@ -178,8 +181,8 @@ int packfrm(const uchar *data, size_t len, if (my_compress((uchar*)data, &org_len, &comp_len)) goto err; - DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", org_len, comp_len)); - DBUG_DUMP("compressed", (char*)data, org_len); + DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", (ulong) org_len, (ulong) comp_len)); + DBUG_DUMP("compressed", data, org_len); error= 2; blob_len= BLOB_HEADER + org_len; @@ -235,7 +238,7 @@ int unpackfrm(uchar **unpack_data, size_t *unpack_len, complen= uint4korr(pack_data+8); DBUG_PRINT("blob",("ver: %lu complen: %lu orglen: %lu", - ver, complen, orglen)); + ver, (ulong) complen, (ulong) orglen)); DBUG_DUMP("blob->data", pack_data + BLOB_HEADER, complen); if (ver != 1) diff --git a/mysys/my_copy.c b/mysys/my_copy.c index 3f8b0695a25..cd741b1eb52 100644 --- a/mysys/my_copy.c +++ b/mysys/my_copy.c @@ -54,7 +54,7 @@ int my_copy(const char *from, const char *to, myf MyFlags) my_bool new_file_stat= 0; /* 1 if we could stat "to" */ int create_flag; File from_file,to_file; - char buff[IO_SIZE]; + uchar buff[IO_SIZE]; MY_STAT stat_buff,new_stat_buff; DBUG_ENTER("my_copy"); DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); @@ -80,10 +80,12 @@ int my_copy(const char *from, const char *to, myf MyFlags) MyFlags)) < 0) goto err; - while ((Count=my_read(from_file,buff,IO_SIZE,MyFlags)) != 0) + while ((Count=my_read(from_file, buff, sizeof(buff), MyFlags)) != 0) + { if (Count == (uint) -1 || my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP))) goto err; + } if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags)) DBUG_RETURN(-1); /* Error on close */ diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index 01abc02058b..845b5aa4152 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -19,7 +19,7 @@ #include "mysys_priv.h" #include <m_string.h> -#ifndef MAIN +#if !defined(__FreeBSD__) || defined(__linux__) static my_bool memcpy_and_test(uchar *to, uchar *from, uint len) { uint i, res=1; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 32a5452e451..3a5b130e067 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -32,6 +32,7 @@ my_bool getopt_compare_strings(const char *s, static longlong getopt_ll(char *arg, const struct my_option *optp, int *err); static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err); +static double getopt_double(char *arg, const struct my_option *optp, int *err); static void init_variables(const struct my_option *options); static int setval(const struct my_option *opts, uchar* *value, char *argument, my_bool set_maximum_value); @@ -611,6 +612,9 @@ static int setval(const struct my_option *opts, uchar* *value, char *argument, case GET_ULL: *((ulonglong*) result_pos)= getopt_ull(argument, opts, &err); break; + case GET_DOUBLE: + *((double*) result_pos)= getopt_double(argument, opts, &err); + break; case GET_STR: *((char**) result_pos)= argument; break; @@ -720,7 +724,7 @@ my_bool getopt_compare_strings(register const char *s, register const char *t, be k|K for kilo, m|M for mega or g|G for giga. */ -static longlong eval_num_suffix (char *argument, int *error, char *option_name) +static longlong eval_num_suffix(char *argument, int *error, char *option_name) { char *endchar; longlong num; @@ -802,6 +806,37 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp) /* + Get double value withing ranges + + Evaluates and returns the value that user gave as an argument to a variable. + + RETURN + decimal value of arg + + In case of an error, prints an error message and sets *err to + EXIT_ARGUMENT_INVALID. Otherwise err is not touched +*/ + +static double getopt_double(char *arg, const struct my_option *optp, int *err) +{ + double num; + int error; + char *end= arg + 1000; /* Big enough as *arg is \0 terminated */ + num= my_strtod(arg, &end, &error); + if (end[0] != 0 || error) + { + fprintf(stderr, + "%s: ERROR: Invalid decimal value for option '%s'\n", + my_progname, optp->name); + *err= EXIT_ARGUMENT_INVALID; + return 0.0; + } + if (optp->max_value && num > (double) optp->max_value) + num= (double) optp->max_value; + return max(num, (double) optp->min_value); +} + +/* Init one value to it's default values SYNOPSIS @@ -838,6 +873,9 @@ static void init_one_value(const struct my_option *option, uchar* *variable, case GET_SET: *((ulonglong*) variable)= (ulonglong) value; break; + case GET_DOUBLE: + *((double*) variable)= (double) value; + break; case GET_STR: /* Do not clear variable value if it has no default value. @@ -1052,6 +1090,9 @@ void my_print_variables(const struct my_option *options) longlong2str(*((ulonglong*) value), buff, 10); printf("%s\n", buff); break; + case GET_DOUBLE: + printf("%g\n", *(double*) value); + break; default: printf("(Disabled)\n"); break; diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c index 2fd7eed7778..43bb6c08af9 100644 --- a/mysys/my_getsystime.c +++ b/mysys/my_getsystime.c @@ -17,11 +17,13 @@ /* thus to get the current time we should use the system function with the highest possible resolution */ +#include "mysys_priv.h" +#include "my_static.h" + #ifdef __NETWARE__ #include <nks/time.h> #endif -#include "mysys_priv.h" ulonglong my_getsystime() { #ifdef HAVE_CLOCK_GETTIME @@ -29,28 +31,15 @@ ulonglong my_getsystime() clock_gettime(CLOCK_REALTIME, &tp); return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100; #elif defined(__WIN__) -#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10) - static __int64 offset=0, freq; LARGE_INTEGER t_cnt; - if (!offset) + if (query_performance_frequency) { - /* strictly speaking there should be a mutex to protect - initialization section. But my_getsystime() is called from - UUID() code, and UUID() calls are serialized with a mutex anyway - */ - LARGE_INTEGER li; - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - li.LowPart=ft.dwLowDateTime; - li.HighPart=ft.dwHighDateTime; - offset=li.QuadPart-OFFSET_TO_EPOC; - QueryPerformanceFrequency(&li); - freq=li.QuadPart; QueryPerformanceCounter(&t_cnt); - offset-=t_cnt.QuadPart/freq*10000000+t_cnt.QuadPart%freq*10000000/freq; + return (t_cnt.QuadPart / query_performance_frequency * 10000000+ + t_cnt.QuadPart % query_performance_frequency * 10000000/ + query_performance_frequency+query_performance_offset); } - QueryPerformanceCounter(&t_cnt); - return t_cnt.QuadPart/freq*10000000+t_cnt.QuadPart%freq*10000000/freq+offset; + return 0; #elif defined(__NETWARE__) NXTime_t tm; NXGetTime(NX_SINCE_1970, NX_NSECONDS, &tm); @@ -62,3 +51,176 @@ ulonglong my_getsystime() return (ulonglong)tv.tv_sec*10000000+(ulonglong)tv.tv_usec*10; #endif } + + +/* + Return current time + + SYNOPSIS + my_time() + flags If MY_WME is set, write error if time call fails + +*/ + +time_t my_time(myf flags __attribute__((unused))) +{ + time_t t; +#ifdef HAVE_GETHRTIME + (void) my_micro_time_and_time(&t); + return t; +#else + /* The following loop is here beacuse time() may fail on some systems */ + while ((t= time(0)) == (time_t) -1) + { + if (flags & MY_WME) + fprintf(stderr, "%s: Warning: time() call failed\n", my_progname); + } + return t; +#endif +} + + +/* + Return time in micro seconds + + SYNOPSIS + my_micro_time() + + NOTES + This function is to be used to measure performance in micro seconds. + As it's not defined whats the start time for the clock, this function + us only useful to measure time between two moments. + + For windows platforms we need the frequency value of the CUP. This is + initalized in my_init.c through QueryPerformanceFrequency(). + + If Windows platform doesn't support QueryPerformanceFrequency() we will + obtain the time via GetClockCount, which only supports milliseconds. + + RETURN + Value in microseconds from some undefined point in time +*/ + +ulonglong my_micro_time() +{ + ulonglong newtime; +#if defined(__WIN__) + if (query_performance_frequency) + { + QueryPerformanceCounter((LARGE_INTEGER*) &newtime); + newtime/= (query_performance_frequency * 1000000); + } + else + newtime= (GetTickCount() * 1000); /* GetTickCount only returns milliseconds */ + return newtime; +#elif defined(HAVE_GETHRTIME) + return gethrtime()/1000; +#else + struct timeval t; + /* The following loop is here because gettimeofday may fail on some systems */ + while (gettimeofday(&t, NULL) != 0) + {} + newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec; + return newtime; +#endif /* defined(__WIN__) */ +} + + +/* + Return time in seconds and timer in microseconds (not different start!) + + SYNOPSIS + my_micro_time_and_time() + time_arg Will be set to seconds since epoch (00:00:00 UTC, January 1, + 1970) + + NOTES + This function is to be useful when we need both the time and microtime. + For example in MySQL this is used to get the query time start of a query and + to measure the time of a query (for the slow query log) + + IMPLEMENTATION + Value of time is as in time() call. + Value of microtime is same as my_micro_time(), which may be totally unrealated + to time() + + RETURN + Value in microseconds from some undefined point in time +*/ + +#define DELTA_FOR_SECONDS LL(500000000) /* Half a second */ + +ulonglong my_micro_time_and_time(time_t *time_arg) +{ + ulonglong newtime; +#if defined(__WIN__) + if (query_performance_frequency) + { + QueryPerformanceCounter((LARGE_INTEGER*) &newtime); + newtime/= (query_performance_frequency * 1000000); + } + else + newtime= (GetTickCount() * 1000); /* GetTickCount only returns milliseconds */ + (void) time(time_arg); + return newtime; +#elif defined(HAVE_GETHRTIME) + /* + Solaris has a very slow time() call. We optimize this by using the very fast + gethrtime() call and only calling time() every 1/2 second + */ + static hrtime_t prev_gethrtime= 0; + static time_t cur_time= 0; + hrtime_t cur_gethrtime; + + pthread_mutex_lock(&THR_LOCK_time); + cur_gethrtime= gethrtime(); + if ((cur_gethrtime - prev_gethrtime) > DELTA_FOR_SECONDS) + { + cur_time= time(0); + prev_gethrtime= cur_gethrtime; + } + *time_arg= cur_time; + pthread_mutex_unlock(&THR_LOCK_time); + return cur_gethrtime/1000; +#else + struct timeval t; + /* The following loop is here because gettimeofday may fail on some systems */ + while (gettimeofday(&t, NULL) != 0) + {} + *time_arg= t.tv_sec; + newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec; + return newtime; +#endif /* defined(__WIN__) */ +} + + +/* + Returns current time + + SYNOPSIS + my_time_possible_from_micro() + microtime Value from very recent my_micro_time() + + NOTES + This function returns the current time. The microtime argument is only used + if my_micro_time() uses a function that can safely be converted to the current + time. + + RETURN + current time +*/ + +time_t my_time_possible_from_micro(ulonglong microtime __attribute__((unused))) +{ +#if defined(__WIN__) + time_t t; + while ((t= time(0)) == (time_t) -1) + {} + return t; +#elif defined(HAVE_GETHRTIME) + return my_time(0); /* Cached time */ +#else + return (time_t) (microtime / 1000000); +#endif /* defined(__WIN__) */ +} + diff --git a/mysys/my_init.c b/mysys/my_init.c index c1337205eb4..257edb351b4 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -130,17 +130,18 @@ void my_end(int infoflag) */ FILE *info_file= DBUG_FILE; my_bool print_info= (info_file != stderr); - /* We do not use DBUG_ENTER here, as after cleanup DBUG is no longer - operational, so we cannot use DBUG_RETURN. + /* + We do not use DBUG_ENTER here, as after cleanup DBUG is no longer + operational, so we cannot use DBUG_RETURN. */ - DBUG_PRINT("info",("Shutting down")); + DBUG_PRINT("info",("Shutting down: infoflag: %d print_info: %d", + infoflag, print_info)); if (!info_file) { info_file= stderr; print_info= 0; } - DBUG_PRINT("info",("Shutting down: print_info: %d", print_info)); if ((infoflag & MY_CHECK_ERROR) || print_info) { /* Test if some file is left open */ @@ -185,7 +186,7 @@ Voluntary context switches %ld, Involuntary context switches %ld\n", fprintf(info_file,"\nRun time: %.1f\n",(double) clock()/CLOCKS_PER_SEC); #endif #if defined(SAFEMALLOC) - TERMINATE(stderr); /* Give statistic on screen */ + TERMINATE(stderr, (infoflag & MY_GIVE_INFO) != 0); #elif defined(__WIN__) && defined(_MSC_VER) _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE ); _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR ); @@ -197,6 +198,10 @@ Voluntary context switches %ld, Involuntary context switches %ld\n", _CrtDumpMemoryLeaks(); #endif } + else if (infoflag & MY_CHECK_ERROR) + { + TERMINATE(stderr, 0); /* Print memory leaks on screen */ + } if (!(infoflag & MY_DONT_FREE_DBUG)) { @@ -371,6 +376,28 @@ static void my_win_init(void) /* chiude la chiave */ RegCloseKey(hSoftMysql) ; + + /* The following is used by time functions */ +#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10) +#define MS 10000000 + { + FILETIME ft; + LARGE_INTEGER li, t_cnt; + DBUG_ASSERT(sizeof(LARGE_INTEGER) == sizeof(query_performance_frequency)); + if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency)) + query_performance_frequency= 0; + else + { + GetSystemTimeAsFileTime(&ft); + li.LowPart= ft.dwLowDateTime; + li.HighPart= ft.dwHighDateTime; + query_performance_offset= li.QuadPart-OFFSET_TO_EPOC; + QueryPerformanceCounter(&t_cnt); + query_performance_offset-= (t_cnt.QuadPart / query_performance_frequency * MS + + t_cnt.QuadPart % query_performance_frequency * MS / + query_performance_frequency); + } + } DBUG_VOID_RETURN ; } diff --git a/mysys/my_static.c b/mysys/my_static.c index 472cf3b5084..b8bff0e9810 100644 --- a/mysys/my_static.c +++ b/mysys/my_static.c @@ -18,11 +18,9 @@ a shared library */ -#if !defined(stdin) #include "mysys_priv.h" #include "my_static.h" #include "my_alarm.h" -#endif my_bool timed_mutexes= 0; @@ -93,6 +91,11 @@ int (*error_handler_hook)(uint error,const char *str,myf MyFlags)= int (*fatal_error_handler_hook)(uint error,const char *str,myf MyFlags)= my_message_no_curses; +#ifdef __WIN__ +/* from my_getsystime.c */ +ulonglong query_performance_frequency, query_performance_offset; +#endif + /* How to disable options */ my_bool NEAR my_disable_locking=0; my_bool NEAR my_disable_async_io=0; diff --git a/mysys/my_static.h b/mysys/my_static.h index 66e6ea1c280..0eca196c1c9 100644 --- a/mysys/my_static.h +++ b/mysys/my_static.h @@ -66,6 +66,8 @@ extern struct st_irem *sf_malloc_root; extern struct st_my_file_info my_file_info_default[MY_NFILE]; +extern ulonglong query_performance_frequency, query_performance_offset; + #if defined(THREAD) && !defined(__WIN__) extern sigset_t my_signals; /* signals blocked by mf_brkhant */ #endif diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index cc33ac3f21c..8b935c895c8 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -30,7 +30,7 @@ pthread_key(struct st_my_thread_var, THR_KEY_mysys); #endif /* USE_TLS */ pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open, THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap, - THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads; + THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time; pthread_cond_t THR_COND_threads; uint THR_thread_count= 0; uint my_thread_end_wait_time= 5; @@ -146,6 +146,7 @@ my_bool my_thread_global_init(void) pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_threads,MY_MUTEX_INIT_FAST); + pthread_mutex_init(&THR_LOCK_time,MY_MUTEX_INIT_FAST); pthread_cond_init(&THR_COND_threads, NULL); #if defined( __WIN__) || defined(OS2) win_pthread_init(); @@ -202,6 +203,7 @@ void my_thread_global_end(void) pthread_mutex_destroy(&THR_LOCK_myisam); pthread_mutex_destroy(&THR_LOCK_heap); pthread_mutex_destroy(&THR_LOCK_net); + pthread_mutex_destroy(&THR_LOCK_time); pthread_mutex_destroy(&THR_LOCK_charset); if (all_threads_killed) { diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h index 709cfed969a..6e0959ae08c 100644 --- a/mysys/mysys_priv.h +++ b/mysys/mysys_priv.h @@ -28,7 +28,7 @@ #include <my_pthread.h> extern pthread_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache; extern pthread_mutex_t THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_net; -extern pthread_mutex_t THR_LOCK_charset; +extern pthread_mutex_t THR_LOCK_charset, THR_LOCK_time; #else #include <my_no_pthread.h> #endif diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 30c501c54ee..7a2f448b2dc 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -51,7 +51,7 @@ (equivalent to realloc()) FREE( pPtr ) Free memory allocated by NEW (equivalent to free()) - TERMINATE(file) End system, report errors and stats on file + TERMINATE(file,flag) End system, report errors and stats on file I personally use two more functions, but have not included them here: char *STRSAVE( sPtr ) Save a copy of the string in dynamic memory char *RENEW( pPtr, uSize ) @@ -352,12 +352,15 @@ static int check_ptr(const char *where, uchar *ptr, const char *filename, /* - TERMINATE(FILE *file) - Report on all the memory pieces that have not been - free'ed as well as the statistics. + Report on all the memory pieces that have not been free'ed + + SYNOPSIS + TERMINATE() + file Write output to this file + flag If <> 0, also write statistics */ -void TERMINATE(FILE *file) +void TERMINATE(FILE *file, uint flag) { struct st_irem *irem; DBUG_ENTER("TERMINATE"); @@ -373,8 +376,7 @@ void TERMINATE(FILE *file) { if (file) { - fprintf(file, "Warning: Not freed memory segments: %u\n", - sf_malloc_count); + fprintf(file, "Warning: Not freed memory segments: %u\n", sf_malloc_count); (void) fflush(file); } DBUG_PRINT("safe",("sf_malloc_count: %u", sf_malloc_count)); @@ -414,7 +416,7 @@ void TERMINATE(FILE *file) } } /* Report the memory usage statistics */ - if (file) + if (file && flag) { fprintf(file, "Maximum memory usage: %ld bytes (%ldk)\n", sf_malloc_max_memory, (sf_malloc_max_memory + 1023L) / 1024L); diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 81093be3678..2934e724724 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -157,7 +157,7 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data) DBUG_ENTER("thr_alarm"); DBUG_PRINT("enter",("thread: %s sec: %d",my_thread_name(),sec)); - now=(ulong) time((time_t*) 0); + now=(ulong) my_time(0); pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask); pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */ if (alarm_aborted > 0) @@ -351,7 +351,7 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused))) } else { - ulong now=(ulong) time((time_t*) 0); + ulong now=(ulong) my_time(0); ulong next=now+10-(now%10); while ((alarm_data=(ALARM*) queue_top(&alarm_queue))->expire_time <= now) { @@ -480,7 +480,7 @@ void thr_alarm_info(ALARM_INFO *info) info->max_used_alarms= max_used_alarms; if ((info->active_alarms= alarm_queue.elements)) { - ulong now=(ulong) time((time_t*) 0); + ulong now=(ulong) my_time(0); long time_diff; ALARM *alarm_data= (ALARM*) queue_top(&alarm_queue); time_diff= (long) (alarm_data->expire_time - now); @@ -528,7 +528,7 @@ static void *alarm_handler(void *arg __attribute__((unused))) { if (alarm_queue.elements) { - ulong sleep_time,now=time((time_t*) 0); + ulong sleep_time,now= my_time(0); if (alarm_aborted) sleep_time=now+1; else @@ -685,7 +685,7 @@ static void *test_thread(void *arg) for (i=1 ; i <= 10 ; i++) { wait_time=param ? 11-i : i; - start_time=time((time_t*) 0); + start_time= my_time(0); if (thr_alarm(&got_alarm,wait_time,0)) { printf("Thread: %s Alarms aborted\n",my_thread_name()); @@ -747,7 +747,7 @@ static void *test_thread(void *arg) } } printf("Thread: %s Slept for %d (%d) sec\n",my_thread_name(), - (int) (time((time_t*) 0)-start_time), wait_time); fflush(stdout); + (int) (my_time(0)-start_time), wait_time); fflush(stdout); thr_end_alarm(&got_alarm); fflush(stdout); } diff --git a/sql-common/client.c b/sql-common/client.c index cdf9eed8574..ce891a37b21 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -232,7 +232,7 @@ static int wait_for_data(my_socket fd, uint timeout) implementations of select that don't adjust tv upon failure to reflect the time remaining */ - start_time = time(NULL); + start_time= my_time(0); for (;;) { tv.tv_sec = (long) timeout; @@ -246,7 +246,7 @@ static int wait_for_data(my_socket fd, uint timeout) #endif if (res == 0) /* timeout */ return -1; - now_time=time(NULL); + now_time= my_time(0); timeout-= (uint) (now_time - start_time); if (errno != EINTR || (int) timeout <= 0) return -1; diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 144a87e13f6..2ab77ad6b11 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -1645,7 +1645,7 @@ err: void Event_queue_element::mark_last_executed(THD *thd) { - thd->end_time(); + thd->set_current_time(); last_executed= (my_time_t) thd->query_start(); last_executed_changed= TRUE; diff --git a/sql/event_queue.cc b/sql/event_queue.cc index 04449dd48a1..95f207844fc 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -550,7 +550,7 @@ Event_queue::get_top_for_execution_if_time(THD *thd, top= ((Event_queue_element*) queue_element(&queue, 0)); - thd->end_time(); /* Get current time */ + thd->set_current_time(); /* Get current time */ next_activation_at= top->execute_at; if (next_activation_at > thd->query_start()) diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index c552b22e942..3092521fd4c 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -283,8 +283,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event) res= post_init_event_thread(thd); DBUG_ENTER("Event_worker_thread::run"); - DBUG_PRINT("info", ("Time is %ld, THD: 0x%lx", - (long) time(NULL), (long) thd)); + DBUG_PRINT("info", ("Time is %ld, THD: 0x%lx", (long) my_time(0), (long) thd)); if (res) goto end; diff --git a/sql/field.h b/sql/field.h index 8bf087c7ebd..2782042e911 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1394,6 +1394,8 @@ public: { return charset() == &my_charset_bin ? FALSE : TRUE; } uint32 max_display_length(); uint is_equal(Create_field *new_field); + inline bool in_read_set() { return bitmap_is_set(table->read_set, field_index); } + inline bool in_write_set() { return bitmap_is_set(table->write_set, field_index); } }; diff --git a/sql/item.h b/sql/item.h index 432da6c3a1c..c15b74a265d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1712,8 +1712,11 @@ public: max_length=length; fixed= 1; } - Item_float(double value_par) :presentation(0), value(value_par) { fixed= 1; } - + Item_float(double value_par, uint decimal_par) :presentation(0), value(value_par) + { + decimals= (uint8) decimal_par; + fixed= 1; + } int save_in_field(Field *field, bool no_conversions); enum Type type() const { return REAL_ITEM; } enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index fcbacc32d88..47914c59b4c 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -853,6 +853,7 @@ public: friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b); }; + class in_double :public in_vector { double tmp; @@ -862,16 +863,16 @@ public: uchar *get_value(Item *item); Item *create_item() { - return new Item_float(0.0); + return new Item_float(0.0, 0); } void value_to_item(uint pos, Item *item) { ((Item_float*)item)->value= ((double*) base)[pos]; } Item_result result_type() { return REAL_RESULT; } - }; + class in_decimal :public in_vector { my_decimal val; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index a87efa9e68c..7cee8088026 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1594,7 +1594,7 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions) void Item_func_sysdate_local::store_now_in_TIME(MYSQL_TIME *now_time) { THD *thd= current_thd; - thd->variables.time_zone->gmt_sec_to_TIME(now_time, (my_time_t) time(NULL)); + thd->variables.time_zone->gmt_sec_to_TIME(now_time, (my_time_t) my_time(0)); thd->time_zone_used= 1; } diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index f8457a1ae50..067af930d6f 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -2769,7 +2769,7 @@ String *Item_xml_str_func::parse_xml(String *raw_xml, String *parsed_xml_buf) char buf[128]; my_snprintf(buf, sizeof(buf)-1, "parse error at line %d pos %lu: %s", my_xml_error_lineno(&p) + 1, - my_xml_error_pos(&p) + 1, + (ulong) my_xml_error_pos(&p) + 1, my_xml_error_string(&p)); push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WRONG_VALUE, diff --git a/sql/lock.cc b/sql/lock.cc index 08ff90ce983..8e13c42d6d4 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -326,7 +326,7 @@ retry: } } - thd->lock_time(); + thd->set_time_after_lock(); DBUG_RETURN (sql_lock); } diff --git a/sql/log.cc b/sql/log.cc index dbb664c9d18..c5c84cfb11f 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -455,8 +455,8 @@ err: user_host the pointer to the string with user@host info user_host_len length of the user_host string. this is computed once and passed to all general log event handlers - query_time Amount of time the query took to execute (in seconds) - lock_time Amount of time the query was locked (in seconds) + query_time Amount of time the query took to execute (in microseconds) + lock_time Amount of time the query was locked (in microseconds) is_command The flag, which determines, whether the sql_text is a query or an administrator command (these are treated differently by the old logging routines) @@ -476,7 +476,7 @@ err: bool Log_to_csv_event_handler:: log_slow(THD *thd, time_t current_time, time_t query_start_arg, const char *user_host, uint user_host_len, - longlong query_time, longlong lock_time, bool is_command, + ulonglong query_utime, ulonglong lock_utime, bool is_command, const char *sql_text, uint sql_text_len) { TABLE_LIST table_list; @@ -491,7 +491,6 @@ bool Log_to_csv_event_handler:: time_t save_user_time; bool save_time_zone_used; CHARSET_INFO *client_cs= thd->variables.character_set_client; - DBUG_ENTER("Log_to_csv_event_handler::log_slow"); bzero(& table_list, sizeof(TABLE_LIST)); @@ -540,6 +539,8 @@ bool Log_to_csv_event_handler:: if (query_start_arg) { + longlong query_time= (longlong) (query_utime/1000000); + longlong lock_time= (longlong) (lock_utime/1000000); /* A TIME field can not hold the full longlong range; query_time or lock_time may be truncated without warning here, if greater than @@ -705,12 +706,12 @@ void Log_to_file_event_handler::init_pthread_objects() bool Log_to_file_event_handler:: log_slow(THD *thd, time_t current_time, time_t query_start_arg, const char *user_host, uint user_host_len, - longlong query_time, longlong lock_time, bool is_command, + ulonglong query_utime, ulonglong lock_utime, bool is_command, const char *sql_text, uint sql_text_len) { return mysql_slow_log.write(thd, current_time, query_start_arg, user_host, user_host_len, - query_time, lock_time, is_command, + query_utime, lock_utime, is_command, sql_text, sql_text_len); } @@ -785,10 +786,10 @@ bool LOGGER::error_log_print(enum loglevel level, const char *format, va_list args) { bool error= FALSE; - Log_event_handler **current_handler= error_log_handler_list; + Log_event_handler **current_handler; /* currently we don't need locking here as there is no error_log table */ - while (*current_handler) + for (current_handler= error_log_handler_list ; *current_handler ;) error= (*current_handler++)->log_error(level, format, args) || error; return error; @@ -878,28 +879,27 @@ bool LOGGER::flush_logs(THD *thd) SYNOPSIS slow_log_print() - thd THD of the query being logged - query The query being logged - query_length The length of the query string - query_start_arg Query start timestamp + thd THD of the query being logged + query The query being logged + query_length The length of the query string + current_utime Current time in microseconds (from undefined start) RETURN - FALSE - OK - TRUE - error occured + FALSE OK + TRUE error occured */ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length, - time_t query_start_arg) + ulonglong current_utime) + { bool error= FALSE; - Log_event_handler **current_handler= slow_log_handler_list; + Log_event_handler **current_handler; bool is_command= FALSE; char user_host_buff[MAX_USER_HOST_SIZE]; - - time_t current_time; Security_context *sctx= thd->security_ctx; uint user_host_len= 0; - longlong query_time= 0, lock_time= 0; + ulonglong query_utime, lock_utime; /* Print the message to the buffer if we have slow log enabled @@ -907,10 +907,10 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length, if (*slow_log_handler_list) { - current_time= time(NULL); + time_t current_time; /* do not log slow queries from replication threads */ - if (thd->slave_thread) + if (thd->slave_thread && !opt_log_slow_slave_statements) return 0; lock_shared(); @@ -921,17 +921,22 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length, } /* fill in user_host value: the format is "%s[%s] @ %s [%s]" */ - user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE, - sctx->priv_user ? sctx->priv_user : "", "[", - sctx->user ? sctx->user : "", "] @ ", - sctx->host ? sctx->host : "", " [", - sctx->ip ? sctx->ip : "", "]", NullS) - - user_host_buff; - - if (query_start_arg) + user_host_len= (strxnmov(user_host_buff, MAX_USER_HOST_SIZE, + sctx->priv_user ? sctx->priv_user : "", "[", + sctx->user ? sctx->user : "", "] @ ", + sctx->host ? sctx->host : "", " [", + sctx->ip ? sctx->ip : "", "]", NullS) - + user_host_buff); + + current_time= my_time_possible_from_micro(current_utime); + if (thd->start_utime) + { + query_utime= (current_utime - thd->start_utime); + lock_utime= (thd->utime_after_lock - thd->start_utime); + } + else { - query_time= (longlong) (current_time - query_start_arg); - lock_time= (longlong) (thd->time_after_lock - query_start_arg); + query_utime= lock_utime= 0; } if (!query) @@ -941,10 +946,10 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length, query_length= command_name[thd->command].length; } - while (*current_handler) - error= (*current_handler++)->log_slow(thd, current_time, query_start_arg, + for (current_handler= slow_log_handler_list; *current_handler ;) + error= (*current_handler++)->log_slow(thd, current_time, thd->start_time, user_host_buff, user_host_len, - query_time, lock_time, is_command, + query_utime, lock_utime, is_command, query, query_length) || error; unlock(); @@ -969,7 +974,7 @@ bool LOGGER::general_log_print(THD *thd, enum enum_server_command command, Security_context *sctx= thd->security_ctx; ulong id; uint message_buff_len= 0, user_host_len= 0; - + time_t current_time; if (thd) { /* Normal thread */ if ((thd->options & OPTION_LOG_OFF) @@ -991,8 +996,6 @@ bool LOGGER::general_log_print(THD *thd, enum enum_server_command command, unlock(); return 0; } - time_t current_time= time(NULL); - user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE, sctx->priv_user ? sctx->priv_user : "", "[", sctx->user ? sctx->user : "", "] @ ", @@ -1007,6 +1010,7 @@ bool LOGGER::general_log_print(THD *thd, enum enum_server_command command, else message_buff[0]= '\0'; + current_time= my_time(0); while (*current_handler) error+= (*current_handler++)-> log_general(thd, current_time, user_host_buff, @@ -2022,8 +2026,8 @@ err: user_host the pointer to the string with user@host info user_host_len length of the user_host string. this is computed once and passed to all general log event handlers - query_time Amount of time the query took to execute (in seconds) - lock_time Amount of time the query was locked (in seconds) + query_utime Amount of time the query took to execute (in microseconds) + lock_utime Amount of time the query was locked (in microseconds) is_command The flag, which determines, whether the sql_text is a query or an administrator command. sql_text the very text of the query or administrator command @@ -2041,8 +2045,8 @@ err: bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, time_t query_start_arg, const char *user_host, - uint user_host_len, longlong query_time, - longlong lock_time, bool is_command, + uint user_host_len, ulonglong query_utime, + ulonglong lock_utime, bool is_command, const char *sql_text, uint sql_text_len) { bool error= 0; @@ -2060,6 +2064,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, { // Safety agains reopen int tmp_errno= 0; char buff[80], *end; + char query_time_buff[22+7], lock_time_buff[22+7]; uint buff_len; end= buff; @@ -2090,10 +2095,12 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, tmp_errno= errno; } /* For slow query log */ + sprintf(query_time_buff, "%.6f", ulonglong2double(query_utime)/1000000.0); + sprintf(lock_time_buff, "%.6f", ulonglong2double(lock_utime)/1000000.0); if (my_b_printf(&log_file, - "# Query_time: %lu Lock_time: %lu" + "# Query_time: %s Lock_time: %s" " Rows_sent: %lu Rows_examined: %lu\n", - (ulong) query_time, (ulong) lock_time, + query_time_buff, lock_time_buff, (ulong) thd->sent_row_count, (ulong) thd->examined_row_count) == (uint) -1) tmp_errno= errno; @@ -3735,9 +3742,9 @@ int error_log_print(enum loglevel level, const char *format, bool slow_log_print(THD *thd, const char *query, uint query_length, - time_t query_start_arg) + ulonglong current_utime) { - return logger.slow_log_print(thd, query, query_length, query_start_arg); + return logger.slow_log_print(thd, query, query_length, current_utime); } @@ -3765,7 +3772,7 @@ void MYSQL_BIN_LOG::rotate_and_purge(uint flags) #ifdef HAVE_REPLICATION if (expire_logs_days) { - time_t purge_time= time(0) - expire_logs_days*24*60*60; + time_t purge_time= my_time(0) - expire_logs_days*24*60*60; if (purge_time >= 0) purge_logs_before_date(purge_time); } @@ -4362,7 +4369,7 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer) VOID(pthread_mutex_lock(&LOCK_error_log)); - skr=time(NULL); + skr= my_time(0); localtime_r(&skr, &tm_tmp); start=&tm_tmp; diff --git a/sql/log.h b/sql/log.h index 3b1a0950daa..c116c4a93f7 100644 --- a/sql/log.h +++ b/sql/log.h @@ -198,7 +198,7 @@ public: const char *sql_text, uint sql_text_len); bool write(THD *thd, time_t current_time, time_t query_start_arg, const char *user_host, uint user_host_len, - longlong query_time, longlong lock_time, bool is_command, + ulonglong query_utime, ulonglong lock_utime, bool is_command, const char *sql_text, uint sql_text_len); bool open_slow_log(const char *log_name) { @@ -394,8 +394,8 @@ public: virtual bool log_slow(THD *thd, time_t current_time, time_t query_start_arg, const char *user_host, - uint user_host_len, longlong query_time, - longlong lock_time, bool is_command, + uint user_host_len, ulonglong query_utime, + ulonglong lock_utime, bool is_command, const char *sql_text, uint sql_text_len)= 0; virtual bool log_error(enum loglevel level, const char *format, va_list args)= 0; @@ -423,8 +423,8 @@ public: virtual bool log_slow(THD *thd, time_t current_time, time_t query_start_arg, const char *user_host, - uint user_host_len, longlong query_time, - longlong lock_time, bool is_command, + uint user_host_len, ulonglong query_utime, + ulonglong lock_utime, bool is_command, const char *sql_text, uint sql_text_len); virtual bool log_error(enum loglevel level, const char *format, va_list args); @@ -455,8 +455,8 @@ public: virtual bool log_slow(THD *thd, time_t current_time, time_t query_start_arg, const char *user_host, - uint user_host_len, longlong query_time, - longlong lock_time, bool is_command, + uint user_host_len, ulonglong query_utime, + ulonglong lock_utime, bool is_command, const char *sql_text, uint sql_text_len); virtual bool log_error(enum loglevel level, const char *format, va_list args); @@ -515,7 +515,7 @@ public: bool error_log_print(enum loglevel level, const char *format, va_list args); bool slow_log_print(THD *thd, const char *query, uint query_length, - time_t query_start_arg); + ulonglong current_utime); bool general_log_print(THD *thd,enum enum_server_command command, const char *format, va_list args); diff --git a/sql/log_event.cc b/sql/log_event.cc index c062aa99b4e..db8729c8318 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -456,7 +456,7 @@ Log_event::Log_event() thd(0) { server_id= ::server_id; - when= time(NULL); + when= my_time(0); log_pos= 0; } #endif /* !MYSQL_CLIENT */ @@ -2073,7 +2073,7 @@ int Query_log_event::do_apply_event(RELAY_LOG_INFO const *rli, /* Execute the query (note that we bypass dispatch_command()) */ const char* found_semicolon= NULL; mysql_parse(thd, thd->query, thd->query_length, &found_semicolon); - + log_slow_statement(thd); } else { @@ -4349,7 +4349,7 @@ int User_var_log_event::do_apply_event(RELAY_LOG_INFO const *rli) switch (type) { case REAL_RESULT: float8get(real_val, val); - it= new Item_float(real_val); + it= new Item_float(real_val, 0); val= (char*) &real_val; // Pointer to value in native format val_len= 8; break; @@ -6173,7 +6173,7 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli) problem. When WL#2975 is implemented, just remove the member st_relay_log_info::last_event_start_time and all its occurences. */ - const_cast<RELAY_LOG_INFO*>(rli)->last_event_start_time= time(0); + const_cast<RELAY_LOG_INFO*>(rli)->last_event_start_time= my_time(0); } DBUG_RETURN(0); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2fe70980ea8..34d92a13945 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -167,6 +167,7 @@ public: void restore_env(THD *thd, Object_creation_ctx *backup_ctx); protected: + Object_creation_ctx() {} virtual Object_creation_ctx *create_backup_ctx(THD *thd) = 0; virtual void change_env(THD *thd) const = 0; @@ -734,7 +735,7 @@ int error_log_print(enum loglevel level, const char *format, va_list args); bool slow_log_print(THD *thd, const char *query, uint query_length, - time_t query_start_arg); + ulonglong current_utime); bool general_log_print(THD *thd, enum enum_server_command command, const char *format,...); @@ -1802,7 +1803,7 @@ extern my_bool opt_readonly, lower_case_file_system; extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs; extern my_bool opt_secure_auth; extern char* opt_secure_file_priv; -extern my_bool opt_log_slow_admin_statements; +extern my_bool opt_log_slow_admin_statements, opt_log_slow_slave_statements; extern my_bool sp_automatic_privileges, opt_noacl; extern my_bool opt_old_style_user_limits, trust_function_creators; extern uint opt_crash_binlog_innodb; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6d22047b9db..33cd55170ea 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -338,6 +338,7 @@ static char *default_collation_name; static char *default_storage_engine_str; static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME; static I_List<THD> thread_cache; +static double long_query_time; static pthread_cond_t COND_thread_cache, COND_flush_thread_cache; @@ -406,6 +407,7 @@ my_bool opt_sync_frm, opt_allow_suspicious_udfs; my_bool opt_secure_auth= 0; char* opt_secure_file_priv= 0; my_bool opt_log_slow_admin_statements= 0; +my_bool opt_log_slow_slave_statements= 0; my_bool lower_case_file_system= 0; my_bool opt_large_pages= 0; my_bool opt_myisam_use_mmap= 0; @@ -1143,7 +1145,7 @@ extern "C" void unireg_abort(int exit_code) sql_print_error("Aborting\n"); else if (opt_help) usage(); - clean_up(exit_code || !opt_bootstrap); /* purecov: inspected */ + clean_up(!opt_help && (exit_code || !opt_bootstrap)); /* purecov: inspected */ DBUG_PRINT("quit",("done with cleanup in unireg_abort")); wait_for_signal_thread_to_end(); clean_up_mutexes(); @@ -1240,12 +1242,12 @@ void clean_up(bool print_message) my_regex_end(); #endif - if (print_message && errmesg) - sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname); #if !defined(EMBEDDED_LIBRARY) if (!opt_bootstrap) (void) my_delete(pidfile_name,MYF(0)); // This may not always exist #endif + if (print_message && errmesg && server_start_time) + sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname); thread_scheduler.end(); finish_client_errs(); my_free((uchar*) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST), @@ -1797,7 +1799,7 @@ static bool cache_thread() this thread for handling of new THD object/connection. */ thd->mysys_var->abort= 0; - thd->thr_create_time= time(NULL); + thd->thr_create_utime= my_micro_time(); threads.append(thd); return(1); } @@ -2174,7 +2176,7 @@ extern "C" sig_handler handle_segfault(int sig) segfaulted = 1; - curr_time= time(NULL); + curr_time= my_time(0); localtime_r(&curr_time, &tm); fprintf(stderr,"\ @@ -2717,7 +2719,7 @@ static int init_common_variables(const char *conf_file_name, int argc, tzset(); // Set tzname max_system_variables.pseudo_thread_id= (ulong)~0; - server_start_time= time((time_t*) 0); + server_start_time= my_time(0); rpl_filter= new Rpl_filter; binlog_filter= new Rpl_filter; if (!rpl_filter || !binlog_filter) @@ -2952,7 +2954,7 @@ static int init_common_variables(const char *conf_file_name, int argc, && !(log_output_options & LOG_NONE)) sql_print_warning("Although a path was specified for the " "--log-slow-queries option, log tables are used. " - "To enable logging to files use the --log-output option."); + "To enable logging to files use the --log-output=file option."); s= opt_logname ? opt_logname : make_default_log_name(buff, ".log"); sys_var_general_log_path.value= my_strdup(s, MYF(0)); @@ -3540,7 +3542,7 @@ server."); #ifdef HAVE_REPLICATION if (opt_bin_log && expire_logs_days) { - time_t purge_time= time(0) - expire_logs_days*24*60*60; + time_t purge_time= server_start_time - expire_logs_days*24*60*60; if (purge_time >= 0) mysql_bin_log.purge_logs_before_date(purge_time); } @@ -4289,7 +4291,7 @@ void create_thread_to_handle_connection(THD *thd) thread_created++; threads.append(thd); DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id)); - thd->connect_time = time(NULL); + thd->connect_utime= thd->start_utime= my_micro_time(); if ((error=pthread_create(&thd->real_id,&connection_attrib, handle_one_connection, (void*) thd))) @@ -5076,6 +5078,8 @@ enum options_mysqld OPT_THREAD_HANDLING, OPT_INNODB_ROLLBACK_ON_TIMEOUT, OPT_SECURE_FILE_PRIV, + OPT_MIN_EXAMINED_ROW_LIMIT, + OPT_LOG_SLOW_SLAVE_STATEMENTS, OPT_OLD_MODE }; @@ -5377,8 +5381,13 @@ Disable with --skip-large-pages.", (uchar**) &opt_log_slow_admin_statements, (uchar**) &opt_log_slow_admin_statements, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"log-slow-slave-statements", OPT_LOG_SLOW_SLAVE_STATEMENTS, + "Log slow statements executed by slave thread to the slow log if it is open.", + (uchar**) &opt_log_slow_slave_statements, + (uchar**) &opt_log_slow_slave_statements, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"log-slow-queries", OPT_SLOW_QUERY_LOG, - "Log slow queries to this log file. Defaults logging to hostname-slow.log file. Must be enabled to activate other slow log options.", + "Log slow queries to a table or log file. Defaults logging to table mysql.slow_log or hostname-slow.log if --log-output=file is used. Must be enabled to activate other slow log options.", (uchar**) &opt_slow_logname, (uchar**) &opt_slow_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-tc", OPT_LOG_TC, @@ -5967,10 +5976,10 @@ log and this option does nothing anymore.", 0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100, 1, 100, 0, 1, 0}, {"long_query_time", OPT_LONG_QUERY_TIME, - "Log all queries that have taken more than long_query_time seconds to execute to file.", - (uchar**) &global_system_variables.long_query_time, - (uchar**) &max_system_variables.long_query_time, 0, GET_ULONG, - REQUIRED_ARG, 10, 1, LONG_TIMEOUT, 0, 1, 0}, + "Log all queries that have taken more than long_query_time seconds to execute to file. " + "The argument will be treated as a decimal value with microsecond precission.", + (uchar**) &long_query_time, (uchar**) &long_query_time, 0, GET_DOUBLE, + REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0}, {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES, "If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive. Should be set to 2 if you are using a case insensitive file system", (uchar**) &lower_case_table_names, @@ -6068,6 +6077,11 @@ The minimum value for this variable is 4096.", "After this many write locks, allow some read locks to run in between.", (uchar**) &max_write_lock_count, (uchar**) &max_write_lock_count, 0, GET_ULONG, REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0}, + {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT, + "Don't log queries which examine less than min_examined_row_limit rows to file.", + (uchar**) &global_system_variables.min_examined_row_limit, + (uchar**) &max_system_variables.min_examined_row_limit, 0, GET_ULONG, + REQUIRED_ARG, 0, 0, ~0L, 0, 1L, 0}, {"multi_range_count", OPT_MULTI_RANGE_COUNT, "Number of key ranges to request at once.", (uchar**) &global_system_variables.multi_range_count, @@ -6959,7 +6973,7 @@ Starts the MySQL database server\n"); printf("Usage: %s [OPTIONS]\n", my_progname); if (!opt_verbose) - puts("\nFor more help options (several pages), use mysqld --verbose --help\n"); + puts("\nFor more help options (several pages), use mysqld --verbose --help"); else { #ifdef __WIN__ @@ -6984,7 +6998,7 @@ Starts the MySQL database server\n"); puts("\n\ To see what values a running MySQL server is using, type\n\ -'mysqladmin variables' instead of 'mysqld --verbose --help'.\n"); +'mysqladmin variables' instead of 'mysqld --verbose --help'."); } } #endif /*!EMBEDDED_LIBRARY*/ @@ -7714,7 +7728,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } return 0; } - /* Initiates DEBUG - but no debugging here ! */ + + +/* Handle arguments for multiple key caches */ static uchar* * mysql_getopt_value(const char *keyname, uint key_length, @@ -7772,9 +7788,10 @@ static void get_options(int *argc,char **argv) (*argc)++; /* add back one for the progname handle_options removes */ /* no need to do this for argv as we are discarding it. */ - if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes) && + if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes || + opt_log_slow_slave_statements) && !opt_slow_log) - sql_print_warning("options --log-slow-admin-statements and --log-queries-not-using-indexes have no effect if --log-slow-queries is not set"); + sql_print_warning("options --log-slow-admin-statements, --log-queries-not-using-indexes and --log-slow-slave-statements have no effect if --log-slow-queries is not set"); #if defined(HAVE_BROKEN_REALPATH) my_use_symdir=0; @@ -7818,6 +7835,10 @@ static void get_options(int *argc,char **argv) /* Set global variables based on startup options */ myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size); + /* long_query_time is in microseconds */ + global_system_variables.long_query_time= max_system_variables.long_query_time= + (longlong) (long_query_time * 1000000.0); + if (opt_short_log_format) opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT; diff --git a/sql/net_serv.cc b/sql/net_serv.cc index bd273145782..1f75d7ab1d7 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -437,7 +437,7 @@ net_write_command(NET *net,uchar command, uchar buff[NET_HEADER_SIZE+1]; uint header_size=NET_HEADER_SIZE+1; DBUG_ENTER("net_write_command"); - DBUG_PRINT("enter",("length: %lu", len)); + DBUG_PRINT("enter",("length: %lu", (ulong) len)); buff[4]=command; /* For first packet */ diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 5ea49396cb4..19fb11ac0cc 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -135,7 +135,7 @@ write_parameter(IO_CACHE *file, uchar* base, File_option *parameter, { /* string have to be allocated already */ LEX_STRING *val_s= (LEX_STRING *)(base + parameter->offset); - time_t tm= time(NULL); + time_t tm= my_time(0); get_date(val_s->str, GETDATE_DATE_TIME|GETDATE_GMT|GETDATE_FIXEDLENGTH, tm); diff --git a/sql/set_var.cc b/sql/set_var.cc index d21a4c18716..97d38cd84ca 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -250,8 +250,8 @@ static sys_var_bool_ptr sys_log_queries_not_using_indexes(&vars, "log_queries_not_using_indexes", &opt_log_queries_not_using_indexes); static sys_var_thd_ulong sys_log_warnings(&vars, "log_warnings", &SV::log_warnings); -static sys_var_thd_ulong sys_long_query_time(&vars, "long_query_time", - &SV::long_query_time); +static sys_var_microseconds sys_var_long_query_time(&vars, "long_query_time", + &SV::long_query_time); static sys_var_thd_bool sys_low_priority_updates(&vars, "low_priority_updates", &SV::low_priority_updates, fix_low_priority_updates); @@ -315,6 +315,8 @@ static sys_var_thd_ulong sys_max_tmp_tables(&vars, "max_tmp_tables", &SV::max_tmp_tables); static sys_var_long_ptr sys_max_write_lock_count(&vars, "max_write_lock_count", &max_write_lock_count); +static sys_var_thd_ulong sys_min_examined_row_limit(&vars, "min_examined_row_limit", + &SV::min_examined_row_limit); static sys_var_thd_ulong sys_multi_range_count(&vars, "multi_range_count", &SV::multi_range_count); static sys_var_long_ptr sys_myisam_data_pointer_size(&vars, "myisam_data_pointer_size", @@ -1473,6 +1475,15 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) pthread_mutex_unlock(&LOCK_global_system_variables); return new Item_int(value); } + case SHOW_DOUBLE: + { + double value; + pthread_mutex_lock(&LOCK_global_system_variables); + value= *(double*) value_ptr(thd, var_type, base); + pthread_mutex_unlock(&LOCK_global_system_variables); + /* 6, as this is for now only used with microseconds */ + return new Item_float(value, 6); + } case SHOW_HA_ROWS: { ha_rows value; @@ -2527,6 +2538,60 @@ void sys_var_thd_lc_time_names::set_default(THD *thd, enum_var_type type) } /* + Handling of microseoncds given as seconds.part_seconds + + NOTES + The argument to long query time is in seconds in decimal + which is converted to ulonglong integer holding microseconds for storage. + This is used for handling long_query_time +*/ + +bool sys_var_microseconds::update(THD *thd, set_var *var) +{ + double num= var->value->val_real(); + longlong microseconds; + if (num > (double) option_limits->max_value) + num= (double) option_limits->max_value; + if (num < (double) option_limits->min_value) + num= (double) option_limits->min_value; + microseconds= (longlong) (num * 1000000.0 + 0.5); + if (var->type == OPT_GLOBAL) + { + pthread_mutex_lock(&LOCK_global_system_variables); + (global_system_variables.*offset)= microseconds; + pthread_mutex_unlock(&LOCK_global_system_variables); + } + else + thd->variables.*offset= microseconds; + return 0; +} + + +void sys_var_microseconds::set_default(THD *thd, enum_var_type type) +{ + longlong microseconds= (longlong) (option_limits->def_value * 1000000.0); + if (type == OPT_GLOBAL) + { + pthread_mutex_lock(&LOCK_global_system_variables); + global_system_variables.*offset= microseconds; + pthread_mutex_unlock(&LOCK_global_system_variables); + } + else + thd->variables.*offset= microseconds; +} + + +uchar *sys_var_microseconds::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) +{ + thd->tmp_double_value= (double) ((type == OPT_GLOBAL) ? + global_system_variables.*offset : + thd->variables.*offset) / 1000000.0; + return (uchar*) &thd->tmp_double_value; +} + + +/* Functions to update thd->options bits */ diff --git a/sql/set_var.h b/sql/set_var.h index a998dc93b84..67ec449a02f 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -113,9 +113,10 @@ class sys_var_long_ptr_global: public sys_var_global { public: ulong *value; - sys_var_long_ptr_global(sys_var_chain *chain, const char *name_arg, ulong *value_ptr_arg, - pthread_mutex_t *guard_arg, - sys_after_update_func after_update_arg= NULL) + sys_var_long_ptr_global(sys_var_chain *chain, const char *name_arg, + ulong *value_ptr_arg, + pthread_mutex_t *guard_arg, + sys_after_update_func after_update_arg= NULL) :sys_var_global(name_arg, after_update_arg, guard_arg), value(value_ptr_arg) { chain_sys_var(chain); } @@ -911,6 +912,27 @@ public: uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); }; + +class sys_var_microseconds :public sys_var_thd +{ + ulonglong SV::*offset; +public: + sys_var_microseconds(sys_var_chain *chain, const char *name_arg, + ulonglong SV::*offset_arg): + sys_var_thd(name_arg), offset(offset_arg) + { chain_sys_var(chain); } + bool check(THD *thd, set_var *var) {return 0;} + bool update(THD *thd, set_var *var); + void set_default(THD *thd, enum_var_type type); + SHOW_TYPE show_type() { return SHOW_DOUBLE; } + bool check_update_type(Item_result type) + { + return (type != INT_RESULT && type != REAL_RESULT && type != DECIMAL_RESULT); + } + uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); +}; + + class sys_var_trust_routine_creators :public sys_var_bool_ptr { /* We need a derived class only to have a warn_deprecated() */ diff --git a/sql/slave.cc b/sql/slave.cc index 96a105b06e4..0854bc123f9 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1460,6 +1460,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) thd->variables.max_allowed_packet= global_system_variables.max_allowed_packet + MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */ thd->slave_thread = 1; + thd->enable_slow_log= opt_log_slow_slave_statements; set_slave_thread_options(thd); thd->client_capabilities = CLIENT_LOCAL_FILES; pthread_mutex_lock(&LOCK_thread_count); @@ -1491,7 +1492,7 @@ static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed, DBUG_ENTER("safe_sleep"); thr_alarm_init(&alarmed); - time_t start_time= time((time_t*) 0); + time_t start_time= my_time(0); time_t end_time= start_time+sec; while ((nap_time= (int) (end_time - start_time)) > 0) @@ -1508,7 +1509,7 @@ static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed, if ((*thread_killed)(thd,thread_killed_arg)) DBUG_RETURN(1); - start_time=time((time_t*) 0); + start_time= my_time(0); } DBUG_RETURN(0); } @@ -1796,7 +1797,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) thd->set_time(); // time the query thd->lex->current_select= 0; if (!ev->when) - ev->when = time(NULL); + ev->when= my_time(0); ev->thd = thd; // because up to this point, ev->thd == 0 int reason= ev->shall_skip(rli); diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 39a7aebcc5d..f6b48afc10b 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -862,6 +862,7 @@ Query_cache::Query_cache(ulong query_cache_limit_arg, ulong Query_cache::resize(ulong query_cache_size_arg) { + ulong new_query_cache_size; DBUG_ENTER("Query_cache::resize"); DBUG_PRINT("qcache", ("from %lu to %lu",query_cache_size, query_cache_size_arg)); @@ -876,17 +877,13 @@ ulong Query_cache::resize(ulong query_cache_size_arg) free_cache(); query_cache_size= query_cache_size_arg; - ulong new_query_cache_size= init_cache(); + new_query_cache_size= init_cache(); STRUCT_LOCK(&structure_guard_mutex); m_cache_status= Query_cache::NO_FLUSH_IN_PROGRESS; - /* - Must not call check_integrity() with - m_cache_status != Query_cache::NO_FLUSH_IN_PROGRESS. - It would wait forever. - */ - DBUG_EXECUTE("check_querycache",check_integrity(1);); pthread_cond_signal(&COND_cache_status_changed); + if (new_query_cache_size) + DBUG_EXECUTE("check_querycache",check_integrity(1);); STRUCT_UNLOCK(&structure_guard_mutex); DBUG_RETURN(new_query_cache_size); diff --git a/sql/sql_cache.h b/sql/sql_cache.h index c4c7e1dbc5e..645807eecbf 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -142,6 +142,7 @@ struct Query_cache_query uint8 tbls_type; unsigned int last_pkt_nr; + Query_cache_query() {} /* Remove gcc warning */ inline void init_n_lock(); void unlock_n_destroy(); inline ulonglong found_rows() { return limit_found_rows; } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 31621c531b0..6a082ae3c8b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -408,7 +408,8 @@ THD::THD() // Must be reset to handle error with THD's created for init of mysqld lex->current_select= 0; start_time=(time_t) 0; - time_after_lock=(time_t) 0; + start_utime= 0L; + utime_after_lock= 0L; current_linfo = 0; slave_thread = 0; bzero(&variables, sizeof(variables)); diff --git a/sql/sql_class.h b/sql/sql_class.h index ff4f3022c2b..368d9758b29 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -249,18 +249,19 @@ struct system_variables ulonglong myisam_max_sort_file_size; ulonglong max_heap_table_size; ulonglong tmp_table_size; + ulonglong long_query_time; ha_rows select_limit; ha_rows max_join_size; ulong auto_increment_increment, auto_increment_offset; ulong bulk_insert_buff_size; ulong join_buff_size; - ulong long_query_time; ulong max_allowed_packet; ulong max_error_count; ulong max_length_for_sort_data; ulong max_sort_length; ulong max_tmp_tables; ulong max_insert_delayed_threads; + ulong min_examined_row_limit; ulong multi_range_count; ulong myisam_repair_threads; ulong myisam_sort_buff_size; @@ -1037,8 +1038,6 @@ public: Security_context main_security_ctx; Security_context *security_ctx; - /* remote (peer) port */ - uint16 peer_port; /* Points to info-string that we show in SHOW PROCESSLIST You are supposed to update thd->proc_info only if you have coded @@ -1046,6 +1045,14 @@ public: */ const char *proc_info; + /* + Used in error messages to tell user in what part of MySQL we found an + error. E. g. when where= "having clause", if fix_fields() fails, user + will know that the error was in having clause. + */ + const char *where; + + double tmp_double_value; /* Used in set_var.cc */ ulong client_capabilities; /* What the client supports */ ulong max_client_packet_length; @@ -1067,14 +1074,12 @@ public: enum enum_server_command command; uint32 server_id; uint32 file_id; // for LOAD DATA INFILE - /* - Used in error messages to tell user in what part of MySQL we found an - error. E. g. when where= "having clause", if fix_fields() fails, user - will know that the error was in having clause. - */ - const char *where; - time_t start_time,time_after_lock,user_time; - time_t connect_time,thr_create_time; // track down slow pthread_create + /* remote (peer) port */ + uint16 peer_port; + time_t start_time, user_time; + ulonglong connect_utime, thr_create_utime; // track down slow pthread_create + ulonglong start_utime, utime_after_lock; + thr_lock_type update_lock_default; Delayed_insert *di; @@ -1582,27 +1587,25 @@ public: proc_info = old_msg; pthread_mutex_unlock(&mysys_var->mutex); } - - static inline void safe_time(time_t *t) + inline time_t query_start() { query_start_used=1; return start_time; } + inline void set_time() { - /** - Wrapper around time() which retries on error (-1) - - @details - This is needed because, despite the documentation, time() may fail - in some circumstances. Here we retry time() until it succeeds, and - log the failure so that performance problems related to this can be - identified. - */ - while(unlikely(time(t) == ((time_t) -1))) - sql_print_information("time() failed with %d", errno); + if (user_time) + { + start_time= user_time; + start_utime= utime_after_lock= my_micro_time(); + } + else + start_utime= utime_after_lock= my_micro_time_and_time(&start_time); } - - inline time_t query_start() { query_start_used=1; return start_time; } - inline void set_time() { if (user_time) start_time=time_after_lock=user_time; else { safe_time(&start_time); time_after_lock= start_time; }} - inline void end_time() { safe_time(&start_time); } - inline void set_time(time_t t) { time_after_lock=start_time=user_time=t; } - inline void lock_time() { safe_time(&time_after_lock); } + inline void set_current_time() { start_time= my_time(MY_WME); } + inline void set_time(time_t t) + { + start_time= user_time= t; + start_utime= utime_after_lock= my_micro_time(); + } + void set_time_after_lock() { utime_after_lock= my_micro_time(); } + ulonglong current_utime() { return my_micro_time(); } inline ulonglong found_rows(void) { return limit_found_rows; diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 26b7098e27c..03b9908c1ad 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -97,7 +97,7 @@ static int get_or_create_user_conn(THD *thd, const char *user, uc->len= temp_len; uc->connections= uc->questions= uc->updates= uc->conn_per_hour= 0; uc->user_resources= *mqh; - uc->intime= thd->thr_create_time; + uc->reset_utime= thd->thr_create_utime; if (my_hash_insert(&hash_user_connections, (uchar*) uc)) { my_free((char*) uc,0); @@ -223,16 +223,16 @@ void decrease_user_connections(USER_CONN *uc) void time_out_user_resource_limits(THD *thd, USER_CONN *uc) { - time_t check_time = thd->start_time ? thd->start_time : time(NULL); + ulonglong check_time= thd->start_utime; DBUG_ENTER("time_out_user_resource_limits"); /* If more than a hour since last check, reset resource checking */ - if (check_time - uc->intime >= 3600) + if (check_time - uc->reset_utime >= LL(3600000000)) { uc->questions=1; uc->updates=0; uc->conn_per_hour=0; - uc->intime=check_time; + uc->reset_utime= check_time; } DBUG_VOID_RETURN; @@ -1053,8 +1053,8 @@ void prepare_new_connection_state(THD* thd) pthread_handler_t handle_one_connection(void *arg) { THD *thd= (THD*) arg; - uint launch_time = - (uint) ((thd->thr_create_time = time(NULL)) - thd->connect_time); + ulong launch_time= (ulong) ((thd->thr_create_utime= my_micro_time()) - + thd->connect_utime); if (thread_scheduler.init_new_connection_thread()) { @@ -1063,7 +1063,7 @@ pthread_handler_t handle_one_connection(void *arg) thread_scheduler.end_thread(thd,0); return 0; } - if (launch_time >= slow_launch_time) + if (launch_time >= slow_launch_time*1000000L) statistic_increment(slow_launch_threads,&LOCK_status); /* diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index dc5db54e128..7272d09b575 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2222,7 +2222,7 @@ pthread_handler_t handle_delayed_insert(void *arg) /* Add thread to THD list so that's it's visible in 'show processlist' */ pthread_mutex_lock(&LOCK_thread_count); thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; - thd->end_time(); + thd->set_current_time(); threads.append(thd); thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED; pthread_mutex_unlock(&LOCK_thread_count); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c98d22d9091..05c0ee49438 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1316,7 +1316,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, void log_slow_statement(THD *thd) { - time_t start_of_query; DBUG_ENTER("log_slow_statement"); /* @@ -1327,25 +1326,24 @@ void log_slow_statement(THD *thd) if (unlikely(thd->in_sub_stmt)) DBUG_VOID_RETURN; // Don't set time for sub stmt - start_of_query= thd->start_time; - thd->end_time(); // Set start time - /* Do not log administrative statements unless the appropriate option is set; do not log into slow log if reading from backup. */ if (thd->enable_slow_log && !thd->user_time) { - thd->proc_info="logging slow query"; + ulonglong end_utime_of_query= thd->current_utime(); - if ((ulong) (thd->start_time - thd->time_after_lock) > - thd->variables.long_query_time || - ((thd->server_status & - (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && - opt_log_queries_not_using_indexes)) + thd->proc_info="logging slow query"; + if (((end_utime_of_query - thd->utime_after_lock) > + thd->variables.long_query_time || + ((thd->server_status & + (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && + opt_log_queries_not_using_indexes)) && + thd->examined_row_count >= thd->variables.min_examined_row_limit) { thd->status_var.long_query_count++; - slow_log_print(thd, thd->query, thd->query_length, start_of_query); + slow_log_print(thd, thd->query, thd->query_length, end_utime_of_query); } } DBUG_VOID_RETURN; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 668b7e99549..c1c3999bc8e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10198,7 +10198,7 @@ static bool open_tmp_table(TABLE *table) { int error; if ((error=table->file->ha_open(table, table->s->table_name.str,O_RDWR, - HA_OPEN_TMP_TABLE))) + HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ table->db_stat=0; @@ -10436,8 +10436,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, /* remove heap table and change to use myisam table */ (void) table->file->ha_rnd_end(); - (void) table->file->close(); - (void) table->file->delete_table(table->s->table_name.str); + (void) table->file->close(); // This deletes the table ! delete table->file; table->file=0; plugin_unlock(0, table->s->db_plugin); @@ -15535,15 +15534,11 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, /* Add "filtered" field to item_list. */ if (join->thd->lex->describe & DESCRIBE_EXTENDED) { - Item_float *filtered; - float f; + float f= 0.0; if (examined_rows) f= (float) (100.0 * join->best_positions[i].records_read / examined_rows); - else - f= 0.0; - item_list.push_back((filtered= new Item_float(f))); - filtered->decimals= 2; + item_list.push_back(new Item_float(f, 2)); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index fdd75fbe844..4a863df64d1 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1663,11 +1663,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) if (mysys_var) pthread_mutex_unlock(&mysys_var->mutex); -#ifdef EXTRA_DEBUG - thd_info->start_time= tmp->time_after_lock; -#else thd_info->start_time= tmp->start_time; -#endif thd_info->query=0; if (tmp->query) { @@ -1686,7 +1682,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) VOID(pthread_mutex_unlock(&LOCK_thread_count)); thread_info *thd_info; - time_t now= time(0); + time_t now= my_time(0); while ((thd_info=thread_infos.get())) { protocol->prepare_for_resend(); @@ -1716,7 +1712,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) TABLE *table= tables->table; CHARSET_INFO *cs= system_charset_info; char *user; - time_t now= time(0); + time_t now= my_time(0); DBUG_ENTER("fill_process_list"); user= thd->security_ctx->master_access & PROCESS_ACL ? @@ -2069,11 +2065,11 @@ static bool show_status_array(THD *thd, const char *wild, */ switch (show_type) { case SHOW_DOUBLE_STATUS: - { value= ((char *) status_var + (ulong) value); - end= buff + sprintf(buff, "%f", *(double*) value); + /* fall through */ + case SHOW_DOUBLE: + end= buff + my_sprintf(buff, (buff, "%f", *(double*) value)); break; - } case SHOW_LONG_STATUS: value= ((char *) status_var + (ulong) value); /* fall through */ @@ -2083,6 +2079,7 @@ static bool show_status_array(THD *thd, const char *wild, break; case SHOW_LONGLONG_STATUS: value= ((char *) status_var + (ulonglong) value); + /* fall through */ case SHOW_LONGLONG: end= longlong10_to_str(*(longlong*) value, buff, 10); break; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7ffb83bc266..9746080e9cd 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -54,6 +54,20 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, HA_CREATE_INFO *create_info, Alter_info *alter_info); +#ifndef DBUG_OFF + +/* Wait until we get a 'mysql_kill' signal */ + +static void wait_for_kill_signal(THD *thd) +{ + while (thd->killed == 0) + sleep(1); + // Reset signal and continue as if nothing happend + thd->killed= THD::NOT_KILLED; +} +#endif + + /* Translate a file name to a table name (WL #1324). @@ -4094,6 +4108,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG); thd->exit_cond(old_message); + DBUG_EXECUTE_IF("wait_in_mysql_admin_table", wait_for_kill_signal(thd);); if (thd->killed) goto err; /* Flush entries in the query cache involving this table. */ diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 5bd01eea68c..0fe299d4505 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -509,7 +509,7 @@ Next alarm time: %lu\n", fflush(stdout); my_checkmalloc(); fprintf(stdout,"\nBegin safemalloc memory dump:\n"); // tag needed for test suite - TERMINATE(stdout); // Write malloc information + TERMINATE(stdout, 1); // Write malloc information fprintf(stdout,"\nEnd safemalloc memory dump.\n"); #ifdef HAVE_MALLINFO diff --git a/sql/structs.h b/sql/structs.h index da2339d27f8..09a3c4d7285 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -209,6 +209,11 @@ typedef struct user_conn { char *user; /* Pointer to host part of the key. */ char *host; + /* + The moment of time when per hour counters were reset last time + (i.e. start of "hour" for conn_per_hour, updates, questions counters). + */ + ulonglong reset_utime; /* Total length of the key. */ uint len; /* Current amount of concurrent connections for this account. */ @@ -220,11 +225,6 @@ typedef struct user_conn { uint conn_per_hour, updates, questions; /* Maximum amount of resources which account is allowed to consume. */ USER_RESOURCES user_resources; - /* - The moment of time when per hour counters were reset last time - (i.e. start of "hour" for conn_per_hour, updates, questions counters). - */ - time_t intime; } USER_CONN; /* Bits in form->update */ diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index f2b67f20c57..2e7c47e17b4 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -22,7 +22,7 @@ #include "mysql_priv.h" #include <mysql/plugin.h> #include "ha_heap.h" - +#include "heapdef.h" static handler *heap_create_handler(handlerton *hton, TABLE_SHARE *table, @@ -61,8 +61,8 @@ static handler *heap_create_handler(handlerton *hton, *****************************************************************************/ ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg) - :handler(hton, table_arg), file(0), records_changed(0), - key_stat_version(0) + :handler(hton, table_arg), file(0), records_changed(0), internal_table(0), + key_stat_version(0) {} @@ -90,13 +90,25 @@ const char **ha_heap::bas_ext() const int ha_heap::open(const char *name, int mode, uint test_if_locked) { - if (!(file= heap_open(name, mode)) && my_errno == ENOENT) + if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || + !(file= heap_open(name, mode)) && my_errno == ENOENT) { HA_CREATE_INFO create_info; + internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE); bzero(&create_info, sizeof(create_info)); + file= 0; if (!create(name, table, &create_info)) { - file= heap_open(name, mode); + file= internal_table ? + heap_open_from_share(internal_share, mode) : + heap_open_from_share_and_register(internal_share, mode); + if (!file) + { + /* Couldn't open table; Remove the newly created table */ + pthread_mutex_lock(&THR_LOCK_heap); + hp_free(internal_share); + pthread_mutex_unlock(&THR_LOCK_heap); + } implicit_emptied= 1; } } @@ -120,7 +132,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) int ha_heap::close(void) { - return heap_close(file); + return internal_table ? hp_close(file) : heap_close(file); } @@ -542,7 +554,7 @@ int ha_heap::delete_table(const char *name) void ha_heap::drop_table(const char *name) { - heap_drop_table(file); + file->s->delete_on_close= 1; close(); } @@ -681,16 +693,16 @@ int ha_heap::create(const char *name, TABLE *table_arg, create_info->auto_increment_value - 1 : 0); hp_create_info.max_table_size=current_thd->variables.max_heap_table_size; hp_create_info.with_auto_increment= found_real_auto_increment; + hp_create_info.internal_table= internal_table; max_rows = (ha_rows) (hp_create_info.max_table_size / mem_per_row); error= heap_create(name, keys, keydef, share->reclength, (ulong) ((share->max_rows < max_rows && share->max_rows) ? share->max_rows : max_rows), - (ulong) share->min_rows, &hp_create_info); + (ulong) share->min_rows, &hp_create_info, &internal_share); my_free((uchar*) keydef, MYF(0)); - if (file) - info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE); + DBUG_ASSERT(file == 0); return (error); } diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h index c414383a4aa..7db775ca15a 100644 --- a/storage/heap/ha_heap.h +++ b/storage/heap/ha_heap.h @@ -25,10 +25,12 @@ class ha_heap: public handler { HP_INFO *file; + HP_SHARE *internal_share; key_map btree_keys; /* number of records changed since last statistics update */ uint records_changed; uint key_stat_version; + my_bool internal_table; public: ha_heap(handlerton *hton, TABLE_SHARE *table); ~ha_heap() {} diff --git a/storage/heap/heapdef.h b/storage/heap/heapdef.h index c43d73eb96d..3fc94062303 100644 --- a/storage/heap/heapdef.h +++ b/storage/heap/heapdef.h @@ -16,6 +16,7 @@ /* This file is included in all heap-files */ #include <my_base.h> /* This includes global */ +C_MODE_START #ifdef THREAD #include <my_pthread.h> #endif @@ -107,3 +108,4 @@ extern pthread_mutex_t THR_LOCK_heap; #define pthread_mutex_lock(A) #define pthread_mutex_unlock(A) #endif +C_MODE_END diff --git a/storage/heap/hp_close.c b/storage/heap/hp_close.c index 79fed859487..d571815980c 100644 --- a/storage/heap/hp_close.c +++ b/storage/heap/hp_close.c @@ -42,7 +42,8 @@ int hp_close(register HP_INFO *info) } #endif info->s->changed=0; - heap_open_list=list_delete(heap_open_list,&info->open_list); + if (info->open_list.data) + heap_open_list=list_delete(heap_open_list,&info->open_list); if (!--info->s->open_count && info->s->delete_on_close) hp_free(info->s); /* Table was deleted */ my_free((uchar*) info,MYF(0)); diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c index b910b89ffcd..b6814fc1614 100644 --- a/storage/heap/hp_create.c +++ b/storage/heap/hp_create.c @@ -19,23 +19,27 @@ static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2); static void init_block(HP_BLOCK *block,uint reclength,ulong min_records, ulong max_records); +/* Create a heap table */ + int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, uint reclength, ulong max_records, ulong min_records, - HP_CREATE_INFO *create_info) + HP_CREATE_INFO *create_info, HP_SHARE **res) { uint i, j, key_segs, max_length, length; - HP_SHARE *share; + HP_SHARE *share= 0; HA_KEYSEG *keyseg; - DBUG_ENTER("heap_create"); - pthread_mutex_lock(&THR_LOCK_heap); - if ((share= hp_find_named_heap(name)) && share->open_count == 0) + if (!create_info->internal_table) { - hp_free(share); - share= NULL; - } - + pthread_mutex_lock(&THR_LOCK_heap); + if ((share= hp_find_named_heap(name)) && share->open_count == 0) + { + hp_free(share); + share= 0; + } + } + if (!share) { HP_KEYDEF *keyinfo; @@ -131,10 +135,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, keys*sizeof(HP_KEYDEF)+ key_segs*sizeof(HA_KEYSEG), MYF(MY_ZEROFILL)))) - { - pthread_mutex_unlock(&THR_LOCK_heap); - DBUG_RETURN(1); - } + goto err; share->keydef= (HP_KEYDEF*) (share + 1); share->key_stat_version= 1; keyseg= (HA_KEYSEG*) (share->keydef + keys); @@ -189,20 +190,33 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, if (!(share->name= my_strdup(name,MYF(0)))) { my_free((uchar*) share,MYF(0)); - pthread_mutex_unlock(&THR_LOCK_heap); - DBUG_RETURN(1); + goto err; } #ifdef THREAD thr_lock_init(&share->lock); VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST)); #endif - share->open_list.data= (void*) share; - heap_share_list= list_add(heap_share_list,&share->open_list); + if (!create_info->internal_table) + { + share->open_list.data= (void*) share; + heap_share_list= list_add(heap_share_list,&share->open_list); + } + else + share->delete_on_close= 1; } - pthread_mutex_unlock(&THR_LOCK_heap); + if (!create_info->internal_table) + pthread_mutex_unlock(&THR_LOCK_heap); + + *res= share; DBUG_RETURN(0); + +err: + if (!create_info->internal_table) + pthread_mutex_unlock(&THR_LOCK_heap); + DBUG_RETURN(1); } /* heap_create */ + static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2) { uint not_used[2]; @@ -279,7 +293,8 @@ void heap_drop_table(HP_INFO *info) void hp_free(HP_SHARE *share) { - heap_share_list= list_delete(heap_share_list, &share->open_list); + if (share->open_list.data) /* If not internal table */ + heap_share_list= list_delete(heap_share_list, &share->open_list); hp_clear(share); /* Remove blocks from memory */ #ifdef THREAD thr_lock_delete(&share->lock); diff --git a/storage/heap/hp_open.c b/storage/heap/hp_open.c index d252704a11b..4d5ec6e27ac 100644 --- a/storage/heap/hp_open.c +++ b/storage/heap/hp_open.c @@ -22,43 +22,34 @@ #include "my_sys.h" -HP_INFO *heap_open(const char *name, int mode) +/* + Open heap table based on HP_SHARE structure + + NOTE + This doesn't register the table in the open table list. +*/ + +HP_INFO *heap_open_from_share(HP_SHARE *share, int mode) { HP_INFO *info; - HP_SHARE *share; + DBUG_ENTER("heap_open_from_share"); - DBUG_ENTER("heap_open"); - pthread_mutex_lock(&THR_LOCK_heap); - if (!(share= hp_find_named_heap(name))) - { - my_errno= ENOENT; - pthread_mutex_unlock(&THR_LOCK_heap); - DBUG_RETURN(0); - } if (!(info= (HP_INFO*) my_malloc((uint) sizeof(HP_INFO) + 2 * share->max_key_length, MYF(MY_ZEROFILL)))) { - pthread_mutex_unlock(&THR_LOCK_heap); DBUG_RETURN(0); } share->open_count++; #ifdef THREAD thr_lock_data_init(&share->lock,&info->lock,NULL); #endif - info->open_list.data= (void*) info; - heap_open_list= list_add(heap_open_list,&info->open_list); - pthread_mutex_unlock(&THR_LOCK_heap); - info->s= share; info->lastkey= (uchar*) (info + 1); info->recbuf= (uchar*) (info->lastkey + share->max_key_length); info->mode= mode; info->current_record= (ulong) ~0L; /* No current record */ - info->current_ptr= 0; - info->current_hash_ptr= 0; info->lastinx= info->errkey= -1; - info->update= 0; #ifndef DBUG_OFF info->opt_flag= READ_CHECK_USED; /* Check when changing */ #endif @@ -68,7 +59,59 @@ HP_INFO *heap_open(const char *name, int mode) DBUG_RETURN(info); } - /* map name to a heap-nr. If name isn't found return 0 */ + +/* + Open heap table based on HP_SHARE structure and register it +*/ + +HP_INFO *heap_open_from_share_and_register(HP_SHARE *share, int mode) +{ + HP_INFO *info; + DBUG_ENTER("heap_open_from_share_and_register"); + + pthread_mutex_lock(&THR_LOCK_heap); + if ((info= heap_open_from_share(share, mode))) + { + info->open_list.data= (void*) info; + heap_open_list= list_add(heap_open_list,&info->open_list); + } + pthread_mutex_unlock(&THR_LOCK_heap); + DBUG_RETURN(info); +} + + +/* + Open heap table based on name + + NOTE + This register the table in the open table list. so that it can be + found by future heap_open() calls. +*/ + +HP_INFO *heap_open(const char *name, int mode) +{ + HP_INFO *info; + HP_SHARE *share; + DBUG_ENTER("heap_open"); + + pthread_mutex_lock(&THR_LOCK_heap); + if (!(share= hp_find_named_heap(name))) + { + my_errno= ENOENT; + pthread_mutex_unlock(&THR_LOCK_heap); + DBUG_RETURN(0); + } + if ((info= heap_open_from_share(share, mode))) + { + info->open_list.data= (void*) info; + heap_open_list= list_add(heap_open_list,&info->open_list); + } + pthread_mutex_unlock(&THR_LOCK_heap); + DBUG_RETURN(info); +} + + +/* map name to a heap-nr. If name isn't found return 0 */ HP_SHARE *hp_find_named_heap(const char *name) { diff --git a/storage/heap/hp_test1.c b/storage/heap/hp_test1.c index aad5677db69..24eea141ad9 100644 --- a/storage/heap/hp_test1.c +++ b/storage/heap/hp_test1.c @@ -37,6 +37,7 @@ int main(int argc, char **argv) HP_KEYDEF keyinfo[10]; HA_KEYSEG keyseg[4]; HP_CREATE_INFO hp_create_info; + HP_SHARE *tmp_share; MY_INIT(argv[0]); filename= "test1"; @@ -52,6 +53,7 @@ int main(int argc, char **argv) keyinfo[0].seg[0].start=1; keyinfo[0].seg[0].length=6; keyinfo[0].seg[0].charset= &my_charset_latin1; + keyinfo[0].seg[0].null_bit= 0; keyinfo[0].flag = HA_NOSAME; deleted=0; @@ -59,7 +61,7 @@ int main(int argc, char **argv) printf("- Creating heap-file\n"); if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000L,10L, - &hp_create_info) || + &hp_create_info, &tmp_share) || !(file= heap_open(filename, 2))) goto err; printf("- Writing records:s\n"); diff --git a/storage/heap/hp_test2.c b/storage/heap/hp_test2.c index 46b1fd61d46..e2a8e2f6926 100644 --- a/storage/heap/hp_test2.c +++ b/storage/heap/hp_test2.c @@ -59,6 +59,7 @@ int main(int argc, char *argv[]) char record[128],record2[128],record3[128],key[10]; const char *filename,*filename2; HP_INFO *file,*file2; + HP_SHARE *tmp_share; HP_KEYDEF keyinfo[MAX_KEYS]; HA_KEYSEG keyseg[MAX_KEYS*5]; HEAP_PTR position; @@ -126,7 +127,7 @@ int main(int argc, char *argv[]) printf("- Creating heap-file\n"); if (heap_create(filename,keys,keyinfo,reclength,(ulong) flag*100000L, - (ulong) recant/2, &hp_create_info) || + (ulong) recant/2, &hp_create_info, &tmp_share) || !(file= heap_open(filename, 2))) goto err; signal(SIGINT,endprog); @@ -562,8 +563,9 @@ int main(int argc, char *argv[]) heap_close(file2); printf("- Creating output heap-file 2\n"); - if (heap_create(filename2,1,keyinfo,reclength,0L,0L,&hp_create_info) || - !(file2= heap_open(filename2, 2))) + if (heap_create(filename2, 1, keyinfo, reclength, 0L, 0L, &hp_create_info, + &tmp_share) || + !(file2= heap_open_from_share_and_register(tmp_share, 2))) goto err; printf("- Copying and removing records\n"); diff --git a/unittest/mysys/base64-t.c b/unittest/mysys/base64-t.c index 7e4afbb3128..1622fe22b4d 100644 --- a/unittest/mysys/base64-t.c +++ b/unittest/mysys/base64-t.c @@ -14,6 +14,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <my_global.h> +#include <my_sys.h> #include <base64.h> #include <tap.h> #include <string.h> @@ -26,6 +27,7 @@ main(void) { int i, cmp; size_t j, k, l, dst_len, needed_length; + MY_INIT("base64-t"); plan(BASE64_LOOP_COUNT * BASE64_ROWS); diff --git a/unittest/mysys/bitmap-t.c b/unittest/mysys/bitmap-t.c index 779508ee228..069a14ff553 100644 --- a/unittest/mysys/bitmap-t.c +++ b/unittest/mysys/bitmap-t.c @@ -18,12 +18,11 @@ library. */ -#include <tap.h> - #include <my_global.h> +#include <my_sys.h> #include <my_bitmap.h> - -#include <string.h> +#include <tap.h> +#include <m_string.h> uint get_rand_bit(uint bitsize) { @@ -379,6 +378,8 @@ int main() int i; int const min_size = 1; int const max_size = 1024; + MY_INIT("bitmap-t"); + plan(max_size - min_size); for (i= min_size; i < max_size; i++) ok(do_test(i) == 0, "bitmap size %d", i); diff --git a/unittest/mysys/my_atomic-t.c b/unittest/mysys/my_atomic-t.c index 8280aff5422..a9e98a95cdb 100644 --- a/unittest/mysys/my_atomic-t.c +++ b/unittest/mysys/my_atomic-t.c @@ -14,9 +14,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <my_global.h> -#include <tap.h> #include <my_sys.h> #include <my_atomic.h> +#include <tap.h> int32 a32,b32,c32; my_atomic_rwlock_t rwl; @@ -160,6 +160,7 @@ err: int main() { int err; + MY_INIT("my_atomic-t.c"); diag("N CPUs: %d", my_getncpus()); err= my_atomic_initialize(); |