diff --git a/client/mysql.cc b/client/mysql.cc index 2ce0d769924..46e15ebbbd3 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -44,7 +44,7 @@ #include #endif -const char *VER= "14.3"; +const char *VER= "14.4"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 @@ -134,7 +134,8 @@ static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, vertical=0, line_numbers=1, column_names=1,opt_html=0, opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0, tty_password= 0, opt_nobeep=0, opt_reconnect=1, - default_charset_used= 0, opt_secure_auth= 0; + default_charset_used= 0, opt_secure_auth= 0, + default_pager_set= 0; static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0; static my_string opt_mysql_unix_port=0; static int connect_flag=CLIENT_INTERACTIVE; @@ -331,8 +332,11 @@ int main(int argc,char *argv[]) strmov(pager, "stdout"); // the default, if --pager wasn't given { char *tmp=getenv("PAGER"); - if (tmp) - strmov(default_pager,tmp); + if (tmp && strlen(tmp)) + { + default_pager_set= 1; + strmov(default_pager, tmp); + } } if (!isatty(0) || !isatty(1)) { @@ -467,6 +471,8 @@ static struct my_option my_long_options[] = { {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"help", 'I', "Synonym for -?", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, + 0, 0, 0, 0, 0}, {"auto-rehash", OPT_AUTO_REHASH, "Enable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time. Disable with --disable-auto-rehash.", (gptr*) &rehash, (gptr*) &rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -484,8 +490,12 @@ static struct my_option my_long_options[] = {"compress", 'C', "Use compression in server/client protocol.", (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, -#ifndef DBUG_OFF - {"debug", '#', "Output debug log.", (gptr*) &default_dbug_option, +#ifdef DBUG_OFF + {"debug", '#', "This is a non-debug version. Catch this and exit", + (gptr*) &default_dbug_option, + (gptr*) &default_dbug_option, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0}, +#else + {"debug", '#', "Output debug log", (gptr*) &default_dbug_option, (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif {"database", 'D', "Database to use.", (gptr*) ¤t_db, @@ -608,19 +618,27 @@ static struct my_option my_long_options[] = GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"connect_timeout", OPT_CONNECT_TIMEOUT, "", (gptr*) &opt_connect_timeout, + {"connect_timeout", OPT_CONNECT_TIMEOUT, + "Number of seconds before connection timeout.", + (gptr*) &opt_connect_timeout, (gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0, 0, 1}, - {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "", + {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, + "Max packet length to send to, or receive from server", (gptr*) &max_allowed_packet, (gptr*) &max_allowed_packet, 0, GET_ULONG, REQUIRED_ARG, 16 *1024L*1024L, 4096, (longlong) 2*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0}, - {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "", + {"net_buffer_length", OPT_NET_BUFFER_LENGTH, + "Buffer for TCP/IP and socket communication", (gptr*) &net_buffer_length, (gptr*) &net_buffer_length, 0, GET_ULONG, REQUIRED_ARG, 16384, 1024, 512*1024*1024L, MALLOC_OVERHEAD, 1024, 0}, - {"select_limit", OPT_SELECT_LIMIT, "", (gptr*) &select_limit, + {"select_limit", OPT_SELECT_LIMIT, + "Automatic limit for SELECT when using --safe-updates", + (gptr*) &select_limit, (gptr*) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ~0L, 0, 1, 0}, - {"max_join_size", OPT_MAX_JOIN_SIZE, "", (gptr*) &max_join_size, + {"max_join_size", OPT_MAX_JOIN_SIZE, + "Automatic limit for rows in a join when using --safe-updates", + (gptr*) &max_join_size, (gptr*) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ~0L, 0, 1, 0}, {"secure-auth", OPT_SECURE_AUTH, "Refuse client connecting to server if it" @@ -689,11 +707,16 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), else { opt_nopager= 0; - if (argument) + if (argument && strlen(argument)) + { + default_pager_set= 1; strmov(pager, argument); - else + strmov(default_pager, pager); + } + else if (default_pager_set) strmov(pager, default_pager); - strmov(default_pager, pager); + else + opt_nopager= 1; } break; case OPT_NOPAGER: @@ -814,6 +837,7 @@ static int get_options(int argc, char **argv) strmov(default_pager, "stdout"); strmov(pager, "stdout"); opt_nopager= 1; + default_pager_set= 0; opt_outfile= 0; opt_reconnect= 0; connect_flag= 0; /* Not in interactive mode */ @@ -2163,12 +2187,17 @@ com_pager(String *buffer, char *line __attribute__((unused))) if (status.batch) return 0; - /* Skip space from file name */ - while (my_isspace(charset_info,*line)) + /* Skip spaces in front of the pager command */ + while (my_isspace(charset_info, *line)) line++; - if (!(param= strchr(line, ' '))) // if pager was not given, use the default + /* Skip the pager command */ + param= strchr(line, ' '); + /* Skip the spaces between the command and the argument */ + while (param && my_isspace(charset_info, *param)) + param++; + if (!param || !strlen(param)) // if pager was not given, use the default { - if (!default_pager[0]) + if (!default_pager_set) { tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n"); opt_nopager=1; @@ -2180,9 +2209,7 @@ com_pager(String *buffer, char *line __attribute__((unused))) } else { - while (my_isspace(charset_info,*param)) - param++; - end=strmake(pager_name, param, sizeof(pager_name)-1); + end= strmake(pager_name, param, sizeof(pager_name)-1); while (end > pager_name && (my_isspace(charset_info,end[-1]) || my_iscntrl(charset_info,end[-1]))) end--; @@ -2191,7 +2218,7 @@ com_pager(String *buffer, char *line __attribute__((unused))) strmov(default_pager, pager_name); } opt_nopager=0; - tee_fprintf(stdout, "PAGER set to %s\n", pager); + tee_fprintf(stdout, "PAGER set to '%s'\n", pager); return 0; } @@ -2202,6 +2229,7 @@ com_nopager(String *buffer __attribute__((unused)), { strmov(pager, "stdout"); opt_nopager=1; + PAGER= stdout; tee_fprintf(stdout, "PAGER set to stdout\n"); return 0; } diff --git a/include/my_getopt.h b/include/my_getopt.h index 148238f8d1b..5f4025efa0e 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -17,11 +17,12 @@ C_MODE_START enum get_opt_var_type { GET_NO_ARG, GET_BOOL, GET_INT, GET_UINT, GET_LONG, - GET_ULONG, GET_LL, GET_ULL, GET_STR, GET_STR_ALLOC + GET_ULONG, GET_LL, GET_ULL, GET_STR, GET_STR_ALLOC, + GET_DISABLED }; -#define GET_ASK_ADDR 128 -#define GET_TYPE_MASK 127 +#define GET_ASK_ADDR 128 +#define GET_TYPE_MASK 127 enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG }; diff --git a/include/mysys_err.h b/include/mysys_err.h index 0ee89e91ee4..230be5f4720 100644 --- a/include/mysys_err.h +++ b/include/mysys_err.h @@ -68,6 +68,7 @@ extern const char * NEAR globerrs[]; /* my_error_messages is here */ #define EXIT_UNKNOWN_SUFFIX 9 #define EXIT_NO_PTR_TO_VARIABLE 10 #define EXIT_CANNOT_CONNECT_TO_SERVICE 11 +#define EXIT_OPTION_DISABLED 12 #ifdef __cplusplus diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 027d7c8fb6e..d2368c5341f 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -2739,8 +2739,6 @@ loop: cnt++; - os_thread_sleep(2000000); - /* Try to track a strange bug reported by Harald Fuchs and others, where the lsn seems to decrease at times */ @@ -2782,6 +2780,8 @@ loop: fflush(stderr); fflush(stdout); + os_thread_sleep(2000000); + if (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) { goto loop; diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index d7a14b8a9ec..e6fdc95fad0 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1512,12 +1512,13 @@ NetWare. */ srv_is_being_started = FALSE; #ifdef UNIV_DEBUG - /* Wait a while so that creates threads have time to suspend themselves - before we switch sync debugging on; otherwise a thread may execute - mutex_enter() before the checks are on, and mutex_exit() after the - checks are on. */ + /* Wait a while so that the created threads have time to suspend + themselves before we switch sync debugging on; otherwise a thread may + execute mutex_enter() before the checks are on, and mutex_exit() after + the checks are on, which will cause an assertion failure in sync + debug. */ - os_thread_sleep(2000000); + os_thread_sleep(3000000); #endif sync_order_checks_on = TRUE; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 76f8f6bf852..b278eaa36e1 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -285,6 +285,19 @@ int handle_options(int *argc, char ***argv, return EXIT_AMBIGUOUS_OPTION; } } + if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED) + { + if (my_getopt_print_errors) + fprintf(stderr, + "%s: %s: Option '%s' used, but is disabled\n", my_progname, + option_is_loose ? "WARNING" : "ERROR", opt_str); + if (option_is_loose) + { + (*argc)--; + continue; + } + return EXIT_OPTION_DISABLED; + } if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG) { if (my_getopt_print_errors) @@ -358,6 +371,14 @@ int handle_options(int *argc, char ***argv, { /* Option recognized. Find next what to do with it */ opt_found= 1; + if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED) + { + if (my_getopt_print_errors) + fprintf(stderr, + "%s: ERROR: Option '-%c' used, but is disabled\n", + my_progname, optp->id); + return EXIT_OPTION_DISABLED; + } if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL && optp->arg_type == NO_ARG) { @@ -550,7 +571,7 @@ static int findopt(char *optpat, uint length, const struct my_option **opt_res, char **ffname) { - int count; + uint count; struct my_option *opt= (struct my_option *) *opt_res; for (count= 0; opt->name; opt++) @@ -562,7 +583,8 @@ static int findopt(char *optpat, uint length, *ffname= (char *) opt->name; /* We only need to know one prev */ if (!opt->name[length]) /* Exact match */ return 1; - count++; + if (!count || strcmp(*ffname, opt->name)) /* Don't count synonyms */ + count++; } } return count; @@ -882,7 +904,8 @@ void my_print_variables(const struct my_option *options) longlong2str(*((ulonglong*) value), buff, 10); printf("%s\n", buff); break; - default: /* dummy default to avoid compiler warnings */ + default: + printf("(Disabled)\n"); break; } } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index fdacc4ec536..45b2b7455f9 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -975,8 +975,13 @@ String *Item_func_right::val_str(String *str) if (res->length() <= (uint) length) return res; /* purecov: inspected */ + /* + As far "res" contains at least "length" bytes + (according to the above condition and return), + the below statement is safe. res->numchars() can + never return a value more than "length". + */ uint start=res->numchars()-(uint) length; - if (start<=0) return res; start=res->charpos(start); tmp_value.set(*res,start,res->length()-start); return &tmp_value; diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 5a9fbf64b1c..1ee88096def 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -220,7 +220,8 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ --includedir=%{_includedir} \ --mandir=%{_mandir} \ --enable-thread-safe-client \ - --with-comment=\"Official MySQL RPM\"; + --with-comment=\"Official MySQL RPM\" \ + --with-readline ; # Add this for more debugging support # --with-debug # Add this for MyISAM RAID support: @@ -574,6 +575,10 @@ fi # The spec file changelog only includes changes made to the spec file # itself %changelog +* Tue Jan 13 2004 Lenz Grimmer + +- link the mysql client against libreadline instead of libedit (BUG 2289) + * Fri Dec 13 2003 Lenz Grimmer - fixed file permissions (BUG 1672)