diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/mysql.cc | 67 | ||||
-rw-r--r-- | client/mysql_upgrade.c | 4 | ||||
-rw-r--r-- | client/mysqlbinlog.cc | 60 | ||||
-rw-r--r-- | client/mysqldump.c | 20 | ||||
-rw-r--r-- | client/mysqltest.c | 134 | ||||
-rw-r--r-- | client/sql_string.cc | 50 | ||||
-rw-r--r-- | client/sql_string.h | 6 |
7 files changed, 178 insertions, 163 deletions
diff --git a/client/mysql.cc b/client/mysql.cc index 28930205635..6d8538d9388 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -131,7 +131,7 @@ 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, connected=0,opt_raw_data=0,unbuffered=0,output_tables=0, - rehash=1,skip_updates=0,safe_updates=0,one_database=0, + opt_rehash=1,skip_updates=0,safe_updates=0,one_database=0, opt_compress=0, using_opt_local_infile=0, vertical=0, line_numbers=1, column_names=1,opt_html=0, opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0, @@ -591,7 +591,8 @@ static struct my_option my_long_options[] = #endif {"auto-rehash", OPT_AUTO_REHASH, "Enable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time. Disable with --disable-auto-rehash.", - (gptr*) &rehash, (gptr*) &rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + (gptr*) &opt_rehash, (gptr*) &opt_rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, + 0, 0}, {"no-auto-rehash", 'A', "No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -898,7 +899,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } break; case 'A': - rehash= 0; + opt_rehash= 0; break; case 'N': column_names= 0; @@ -1756,15 +1757,17 @@ char *rindex(const char *s,int c) static int reconnect(void) { + /* purecov: begin tested */ if (opt_reconnect) { put_info("No connection. Trying to reconnect...",INFO_INFO); (void) com_connect((String *) 0, 0); - if (rehash) + if (opt_rehash) com_rehash(NULL, NULL); } if (!connected) return put_info("Can't connect to the server\n",INFO_ERROR); + /* purecov: end */ return 0; } @@ -2933,7 +2936,7 @@ static int com_connect(String *buffer, char *line) { char *tmp, buff[256]; - bool save_rehash= rehash; + bool save_rehash= opt_rehash; int error; bzero(buff, sizeof(buff)); @@ -2957,13 +2960,16 @@ com_connect(String *buffer, char *line) } } else - rehash= 0; // Quick re-connect + { + /* Quick re-connect */ + opt_rehash= 0; /* purecov: tested */ + } buffer->length(0); // command used } else - rehash= 0; + opt_rehash= 0; error=sql_connect(current_host,current_db,current_user,opt_password,0); - rehash= save_rehash; + opt_rehash= save_rehash; if (connected) { @@ -3125,7 +3131,7 @@ com_use(String *buffer __attribute__((unused)), char *line) current_db=my_strdup(tmp,MYF(MY_WME)); #ifdef HAVE_READLINE if (select_db > 1) - build_completion_hash(rehash, 1); + build_completion_hash(opt_rehash, 1); #endif } @@ -3279,7 +3285,7 @@ sql_real_connect(char *host,char *database,char *user,char *password, mysql.reconnect= 1; #endif #ifdef HAVE_READLINE - build_completion_hash(rehash, 1); + build_completion_hash(opt_rehash, 1); #endif return 0; } @@ -3324,8 +3330,8 @@ static int com_status(String *buffer __attribute__((unused)), char *line __attribute__((unused))) { - const char *status; - char buff[22]; + const char *status_str; + char buff[40]; ulonglong id; MYSQL_RES *result; LINT_INIT(result); @@ -3351,9 +3357,9 @@ com_status(String *buffer __attribute__((unused)), mysql_free_result(result); } #ifdef HAVE_OPENSSL - if ((status= mysql_get_ssl_cipher(&mysql))) + if ((status_str= mysql_get_ssl_cipher(&mysql))) tee_fprintf(stdout, "SSL:\t\t\tCipher in use is %s\n", - status); + status_str); else #endif /* HAVE_OPENSSL */ tee_puts("SSL:\t\t\tNot in use", stdout); @@ -3412,23 +3418,20 @@ com_status(String *buffer __attribute__((unused)), tee_fprintf(stdout, "Protocol:\t\tCompressed\n"); #endif - if ((status=mysql_stat(&mysql)) && !mysql_error(&mysql)[0]) + if ((status_str= mysql_stat(&mysql)) && !mysql_error(&mysql)[0]) { ulong sec; - char buff[40]; - const char *pos= strchr(status,' '); + const char *pos= strchr(status_str,' '); /* print label */ - tee_fprintf(stdout, "%.*s\t\t\t", (int) (pos-status), status); - if ((status=str2int(pos,10,0,LONG_MAX,(long*) &sec))) + tee_fprintf(stdout, "%.*s\t\t\t", (int) (pos-status_str), status_str); + if ((status_str= str2int(pos,10,0,LONG_MAX,(long*) &sec))) { nice_time((double) sec,buff,0); tee_puts(buff, stdout); /* print nice time */ - while (*status == ' ') status++; /* to next info */ - } - if (status) - { + while (*status_str == ' ') + status_str++; /* to next info */ tee_putc('\n', stdout); - tee_puts(status, stdout); + tee_puts(status_str, stdout); } } if (safe_updates) @@ -3448,7 +3451,7 @@ select_limit, max_join_size); } static const char * -server_version_string(MYSQL *mysql) +server_version_string(MYSQL *con) { static char buf[MAX_SERVER_VERSION_LENGTH] = ""; @@ -3458,11 +3461,11 @@ server_version_string(MYSQL *mysql) char *bufp = buf; MYSQL_RES *result; - bufp = strnmov(buf, mysql_get_server_info(mysql), sizeof buf); + bufp= strnmov(buf, mysql_get_server_info(con), sizeof buf); /* "limit 1" is protection against SQL_SELECT_LIMIT=0 */ - if (!mysql_query(mysql, "select @@version_comment limit 1") && - (result = mysql_use_result(mysql))) + if (!mysql_query(con, "select @@version_comment limit 1") && + (result = mysql_use_result(con))) { MYSQL_ROW cur = mysql_fetch_row(result); if (cur && cur[0]) @@ -3552,10 +3555,10 @@ put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate) static int -put_error(MYSQL *mysql) +put_error(MYSQL *con) { - return put_info(mysql_error(mysql), INFO_ERROR, mysql_errno(mysql), - mysql_sqlstate(mysql)); + return put_info(mysql_error(con), INFO_ERROR, mysql_errno(con), + mysql_sqlstate(con)); } @@ -3802,8 +3805,6 @@ static const char* construct_prompt() break; case 'D': char* dateTime; - time_t lclock; - lclock = time(NULL); dateTime = ctime(&lclock); processed_prompt.append(strtok(dateTime,"\n")); break; diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 15f105fd8fe..5ae989c6174 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -449,7 +449,7 @@ int main(int argc, char **argv) char *forced_defaults_file; char *forced_extra_defaults; - char *defaults_group_suffix; + char *local_defaults_group_suffix; const char *script_line; char *upgrade_defaults_path; char *defaults_to_use= NULL; @@ -466,7 +466,7 @@ int main(int argc, char **argv) /* Check if we are forced to use specific defaults */ get_defaults_options(argc, argv, &forced_defaults_file, &forced_extra_defaults, - &defaults_group_suffix); + &local_defaults_group_suffix); load_defaults("my", load_default_groups, &argc, &argv); diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 8242a481c5b..768b24eb2f3 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -94,15 +94,14 @@ static my_bool file_not_closed_error= 0; This is because the event will be created (alloced) in read_log_event() (which returns a pointer) in check_header(). */ -Format_description_log_event* description_event; +Format_description_log_event* glob_description_event; static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, const char* logname); static int dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, const char* logname); static int dump_log_entries(const char* logname); -static int dump_remote_file(NET* net, const char* fname); -static void die(const char* fmt, ...); +static void die(const char* fmt, ...) __attribute__ ((__noreturn__)); static MYSQL* safe_connect(); @@ -603,7 +602,7 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, ce->print(result_file, print_event_info, TRUE); // If this binlog is not 3.23 ; why this test?? - if (description_event->binlog_version >= 3) + if (glob_description_event->binlog_version >= 3) { if (load_processor.process(ce)) break; // Error @@ -638,9 +637,9 @@ Create_file event for file_id: %u\n",exv->file_id); break; } case FORMAT_DESCRIPTION_EVENT: - delete description_event; - description_event= (Format_description_log_event*) ev; - print_event_info->common_header_len= description_event->common_header_len; + delete glob_description_event; + glob_description_event= (Format_description_log_event*) ev; + print_event_info->common_header_len= glob_description_event->common_header_len; ev->print(result_file, print_event_info); /* We don't want this event to be deleted now, so let's hide it (I @@ -1037,7 +1036,7 @@ static int dump_log_entries(const char* logname) This is not as smart as check_header() (used for local log); it will not work for a binlog which mixes format. TODO: fix this. */ -static int check_master_version(MYSQL* mysql, +static int check_master_version(MYSQL *mysql_arg, Format_description_log_event **description_event) { @@ -1045,26 +1044,31 @@ static int check_master_version(MYSQL* mysql, MYSQL_ROW row; const char* version; - if (mysql_query(mysql, "SELECT VERSION()") || - !(res = mysql_store_result(mysql))) + if (mysql_query(mysql_arg, "SELECT VERSION()") || + !(res = mysql_store_result(mysql_arg))) { + /* purecov: begin inspected */ char errmsg[256]; - strmake(errmsg, mysql_error(mysql), sizeof(errmsg)-1); - mysql_close(mysql); + strmake(errmsg, mysql_error(mysql_arg), sizeof(errmsg)-1); + mysql_close(mysql_arg); die("Error checking master version: %s", errmsg); + /* purecov: end */ } if (!(row = mysql_fetch_row(res))) { + /* purecov: begin inspected */ mysql_free_result(res); mysql_close(mysql); die("Master returned no rows for SELECT VERSION()"); - return 1; + /* purecov: end */ } if (!(version = row[0])) { + /* purecov: begin inspected */ mysql_free_result(res); - mysql_close(mysql); + mysql_close(mysql_arg); die("Master reported NULL for the version"); + /* purecov: end */ } switch (*version) { @@ -1083,11 +1087,11 @@ static int check_master_version(MYSQL* mysql, *description_event= new Format_description_log_event(3); break; default: - sql_print_error("Master reported unrecognized MySQL version '%s'", - version); + /* purecov: begin inspected */ mysql_free_result(res); - mysql_close(mysql); - return 1; + mysql_close(mysql_arg); + die("Master reported unrecognized MySQL version '%s'", version); + /* purecov: end */ } mysql_free_result(res); return 0; @@ -1115,12 +1119,12 @@ static int dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, mysql= safe_connect(); net= &mysql->net; - if (check_master_version(mysql, &description_event)) + if (check_master_version(mysql, &glob_description_event)) { fprintf(stderr, "Could not find server version"); DBUG_RETURN(1); } - if (!description_event || !description_event->is_valid()) + if (!glob_description_event || !glob_description_event->is_valid()) { fprintf(stderr, "Invalid Format_description log event; \ could be out of memory"); @@ -1170,7 +1174,7 @@ could be out of memory"); len, net->read_pos[5])); if (!(ev= Log_event::read_log_event((const char*) net->read_pos + 1 , len - 1, &error_msg, - description_event))) + glob_description_event))) { fprintf(stderr, "Could not construct log event object\n"); error= 1; @@ -1178,7 +1182,7 @@ could be out of memory"); } Log_event_type type= ev->get_type_code(); - if (description_event->binlog_version >= 3 || + if (glob_description_event->binlog_version >= 3 || (type != LOAD_EVENT && type != CREATE_FILE_EVENT)) { /* @@ -1384,7 +1388,7 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, my_close(fd, MYF(MY_WME)); return 1; } - check_header(file, &description_event); + check_header(file, &glob_description_event); } else // reading from stdin; { @@ -1406,7 +1410,7 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, if (init_io_cache(file, fileno(stdin), 0, READ_CACHE, (my_off_t) 0, 0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE))) return 1; - check_header(file, &description_event); + check_header(file, &glob_description_event); if (start_position) { /* skip 'start_position' characters from stdin */ @@ -1424,7 +1428,7 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, } } - if (!description_event || !description_event->is_valid()) + if (!glob_description_event || !glob_description_event->is_valid()) die("Invalid Format_description log event; could be out of memory"); if (!start_position && my_b_read(file, tmp_buff, BIN_LOG_HEADER_SIZE)) @@ -1437,14 +1441,14 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, char llbuff[21]; my_off_t old_off = my_b_tell(file); - Log_event* ev = Log_event::read_log_event(file, description_event); + Log_event* ev = Log_event::read_log_event(file, glob_description_event); if (!ev) { /* if binlog wasn't closed properly ("in use" flag is set) don't complain about a corruption, but treat it as EOF and move to the next binlog. */ - if (description_event->flags & LOG_EVENT_BINLOG_IN_USE_F) + if (glob_description_event->flags & LOG_EVENT_BINLOG_IN_USE_F) file->error= 0; else if (file->error) { @@ -1469,7 +1473,7 @@ end: if (fd >= 0) my_close(fd, MYF(MY_WME)); end_io_cache(file); - delete description_event; + delete glob_description_event; return error; } diff --git a/client/mysqldump.c b/client/mysqldump.c index 3b03b0c6751..ec0a9def786 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -115,7 +115,7 @@ 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, err_len= 0, opt_master_data; +static uint opt_mysql_port= 0, opt_master_data; static my_string opt_mysql_unix_port=0; static int first_error=0; static DYNAMIC_STRING extended_row; @@ -746,6 +746,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), char *end= compatible_mode_normal_str; int i; ulong mode; + uint err_len; opt_quoted= 1; opt_set_charset= 0; @@ -883,11 +884,11 @@ static int get_options(int *argc, char ***argv) /* ** DB_error -- prints mysql error message and exits the program. */ -static void DB_error(MYSQL *mysql, const char *when) +static void DB_error(MYSQL *mysql_arg, const char *when) { DBUG_ENTER("DB_error"); fprintf(stderr, "%s: Got error: %d: %s %s\n", my_progname, - mysql_errno(mysql), mysql_error(mysql), when); + mysql_errno(mysql_arg), mysql_error(mysql_arg), when); fflush(stderr); safe_exit(EX_MYSQLERR); DBUG_VOID_RETURN; @@ -1215,7 +1216,7 @@ static void print_quoted_xml(FILE *xml_file, const char *str, ulong len) ..., attribute_name_n, attribute_value_n, NullS) xml_file - output file sbeg - line beginning - send - line ending + line_end - line ending tag_name - XML tag name. first_attribute_name - tag and first attribute first_attribute_value - (Implied) value of first attribute @@ -1235,7 +1236,8 @@ static void print_quoted_xml(FILE *xml_file, const char *str, ulong len) All attribute_value arguments will be quoted before output. */ -static void print_xml_tag(FILE * xml_file, const char* sbeg, const char* send, +static void print_xml_tag(FILE * xml_file, const char* sbeg, + const char* line_end, const char* tag_name, const char* first_attribute_name, ...) { @@ -1265,7 +1267,7 @@ static void print_xml_tag(FILE * xml_file, const char* sbeg, const char* send, va_end(arg_list); fputc('>', xml_file); - fputs(send, xml_file); + fputs(line_end, xml_file); check_io(xml_file); } @@ -1279,7 +1281,7 @@ static void print_xml_tag(FILE * xml_file, const char* sbeg, const char* send, sbeg - line beginning stag_atr - tag and attribute sval - value of attribute - send - line ending + line_end - line ending DESCRIPTION Print tag with one attribute to the xml_file. Format is: @@ -1291,7 +1293,7 @@ static void print_xml_tag(FILE * xml_file, const char* sbeg, const char* send, static void print_xml_null_tag(FILE * xml_file, const char* sbeg, const char* stag_atr, const char* sval, - const char* send) + const char* line_end) { fputs(sbeg, xml_file); fputs("<", xml_file); @@ -1299,7 +1301,7 @@ static void print_xml_null_tag(FILE * xml_file, const char* sbeg, fputs("\"", xml_file); print_quoted_xml(xml_file, sval, strlen(sval)); fputs("\" xsi:nil=\"true\" />", xml_file); - fputs(send, xml_file); + fputs(line_end, xml_file); check_io(xml_file); } diff --git a/client/mysqltest.c b/client/mysqltest.c index 1dc04d008e7..64c8509bfc4 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -84,11 +84,11 @@ enum { }; static int record= 0, opt_sleep= -1; -static char *db= 0, *pass= 0; -const char *user= 0, *host= 0, *unix_sock= 0, *opt_basedir= "./"; +static char *opt_db= 0, *opt_pass= 0; +const char *opt_user= 0, *opt_host= 0, *unix_sock= 0, *opt_basedir= "./"; const char *opt_logdir= ""; const char *opt_include= 0, *opt_charsets_dir; -static int port= 0; +static int opt_port= 0; static int opt_max_connect_retries; static my_bool opt_compress= 0, silent= 0, verbose= 0; static my_bool tty_password= 0; @@ -610,15 +610,14 @@ void check_command_args(struct st_command *command, int i; const char *ptr= arguments; const char *start; - DBUG_ENTER("check_command_args"); DBUG_PRINT("enter", ("num_args: %d", num_args)); + for (i= 0; i < num_args; i++) { const struct command_arg *arg= &args[i]; - switch (arg->type) - { + switch (arg->type) { /* A string */ case ARG_STRING: /* Skip leading spaces */ @@ -783,7 +782,7 @@ void free_used_memory() dynstr_free(&ds_progress); dynstr_free(&ds_warning_messages); free_all_replace(); - my_free(pass,MYF(MY_ALLOW_ZERO_PTR)); + my_free(opt_pass,MYF(MY_ALLOW_ZERO_PTR)); free_defaults(default_argv); free_re(); #ifdef __WIN__ @@ -1313,7 +1312,7 @@ void var_set_errno(int sql_errno) void var_query_set(VAR *var, const char *query, const char** query_end) { - char* end = (char*)((query_end && *query_end) ? + char *end = (char*)((query_end && *query_end) ? *query_end : query + strlen(query)); MYSQL_RES *res; MYSQL_ROW row; @@ -1344,7 +1343,6 @@ void var_query_set(VAR *var, const char *query, const char** query_end) DYNAMIC_STRING result; uint i; ulong *lengths; - char *end; #ifdef NOT_YET MYSQL_FIELD *fields= mysql_fetch_fields(res); #endif @@ -2129,6 +2127,7 @@ void do_perl(struct st_command *command) int do_echo(struct st_command *command) { DYNAMIC_STRING ds_echo; + DBUG_ENTER("do_echo"); init_dynamic_string(&ds_echo, "", command->query_len, 256); do_eval(&ds_echo, command->first_argument, command->end, FALSE); @@ -2136,7 +2135,7 @@ int do_echo(struct st_command *command) dynstr_append_mem(&ds_res, "\n", 1); dynstr_free(&ds_echo); command->last_argument= command->end; - return(0); + DBUG_RETURN(0); } @@ -2432,7 +2431,6 @@ void do_let(struct st_command *command) char *p= command->first_argument; char *var_name, *var_name_end; DYNAMIC_STRING let_rhs_expr; - DBUG_ENTER("do_let"); init_dynamic_string(&let_rhs_expr, "", 512, 2048); @@ -3112,7 +3110,7 @@ int connect_n_handle_errors(struct st_command *command, void do_connect(struct st_command *command) { - int con_port= port; + int con_port= opt_port; char *con_options; bool con_ssl= 0, con_compress= 0; char *ptr; @@ -3248,13 +3246,12 @@ void do_connect(struct st_command *command) /* Use default db name */ if (ds_database.length == 0) - dynstr_set(&ds_database, db); + dynstr_set(&ds_database, opt_db); /* Special database to allow one to connect without a database name */ if (ds_database.length && !strcmp(ds_database.str,"*NO-ONE*")) dynstr_set(&ds_database, ""); - if (connect_n_handle_errors(command, &next_con->mysql, ds_host.str,ds_user.str, ds_password.str, ds_database.str, @@ -3678,7 +3675,7 @@ int read_line(char *buf, int size) void convert_to_format_v1(char* query) { int last_c_was_quote= 0; - char *p= query, *write= query; + char *p= query, *to= query; char *end= strend(query); char last_c; @@ -3686,7 +3683,7 @@ void convert_to_format_v1(char* query) { if (*p == '\n' && !last_c_was_quote) { - *write++ = *p++; /* Save the newline */ + *to++ = *p++; /* Save the newline */ /* Skip any spaces on next line */ while (*p && my_isspace(charset_info, *p)) @@ -3697,19 +3694,19 @@ void convert_to_format_v1(char* query) else if (*p == '\'' || *p == '"' || *p == '`') { last_c= *p; - *write++ = *p++; + *to++ = *p++; /* Copy anything until the next quote of same type */ while (*p && *p != last_c) - *write++ = *p++; + *to++ = *p++; - *write++ = *p++; + *to++ = *p++; last_c_was_quote= 1; } else { - *write++ = *p++; + *to++ = *p++; last_c_was_quote= 0; } } @@ -3827,19 +3824,17 @@ void check_eol_junk(const char *eol) Create a command from a set of lines SYNOPSIS - read_command() - command_ptr pointer where to return the new query + read_command() + command_ptr pointer where to return the new query DESCRIPTION - Converts lines returned by read_line into a command, this involves - parsing the first word in the read line to find the command type. - + Converts lines returned by read_line into a command, this involves + parsing the first word in the read line to find the command type. A -- comment may contain a valid query as the first word after the comment start. Thus it's always checked to see if that is the case. The advantage with this approach is to be able to execute commands terminated by new line '\n' regardless how many "delimiter" it contain. - */ #define MAX_QUERY (256*1024) /* 256K -- a test in sp-big is >128K */ @@ -3925,7 +3920,7 @@ static struct my_option my_long_options[] = {"cursor-protocol", OPT_CURSOR_PROTOCOL, "Use cursors for prepared statements.", (gptr*) &cursor_protocol, (gptr*) &cursor_protocol, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"database", 'D', "Database to use.", (gptr*) &db, (gptr*) &db, 0, + {"database", 'D', "Database to use.", (gptr*) &opt_db, (gptr*) &opt_db, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef DBUG_OFF {"debug", '#', "This is a non-debug version. Catch this and exit", @@ -3936,7 +3931,7 @@ static struct my_option my_long_options[] = #endif {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", (gptr*) &info_flag, (gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0, + {"host", 'h', "Connect to host.", (gptr*) &opt_host, (gptr*) &opt_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"include", 'i', "Include SQL before each test case.", (gptr*) &opt_include, (gptr*) &opt_include, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -3952,8 +3947,8 @@ static struct my_option my_long_options[] = GET_INT, REQUIRED_ARG, 500, 1, 10000, 0, 0, 0}, {"password", 'p', "Password to use when connecting to server.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"port", 'P', "Port number to use for connection.", (gptr*) &port, - (gptr*) &port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"port", 'P', "Port number to use for connection.", (gptr*) &opt_port, + (gptr*) &opt_port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"ps-protocol", OPT_PS_PROTOCOL, "Use prepared statements protocol for communication", (gptr*) &ps_protocol, (gptr*) &ps_protocol, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -3989,8 +3984,8 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"tmpdir", 't', "Temporary directory where sockets are put.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"user", 'u', "User for login.", (gptr*) &user, (gptr*) &user, 0, GET_STR, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"user", 'u', "User for login.", (gptr*) &opt_user, (gptr*) &opt_user, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"verbose", 'v', "Write more.", (gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"version", 'V', "Output version information and exit.", @@ -4117,8 +4112,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'p': if (argument) { - my_free(pass, MYF(MY_ALLOW_ZERO_PTR)); - pass= my_strdup(argument, MYF(MY_FAE)); + my_free(opt_pass, MYF(MY_ALLOW_ZERO_PTR)); + opt_pass= my_strdup(argument, MYF(MY_FAE)); while (*argument) *argument++= 'x'; /* Destroy argument */ tty_password= 0; } @@ -4155,7 +4150,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), exit(0); case '?': usage(); - exit(1); + exit(0); } return 0; } @@ -4175,9 +4170,9 @@ int parse_args(int argc, char **argv) exit(1); } if (argc == 1) - db= *argv; + opt_db= *argv; if (tty_password) - pass=get_tty_password(NullS); + opt_pass= get_tty_password(NullS); /* purify tested */ return 0; } @@ -4462,13 +4457,13 @@ void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res) void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, MYSQL_FIELD *fields, uint num_fields) { - MYSQL_BIND *bind; + MYSQL_BIND *my_bind; my_bool *is_null; ulong *length; uint i; /* Allocate array with bind structs, lengths and NULL flags */ - bind= (MYSQL_BIND*) my_malloc(num_fields * sizeof(MYSQL_BIND), + my_bind= (MYSQL_BIND*) my_malloc(num_fields * sizeof(MYSQL_BIND), MYF(MY_WME | MY_FAE | MY_ZEROFILL)); length= (ulong*) my_malloc(num_fields * sizeof(ulong), MYF(MY_WME | MY_FAE)); @@ -4479,25 +4474,25 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, for (i= 0; i < num_fields; i++) { uint max_length= fields[i].max_length + 1; - bind[i].buffer_type= MYSQL_TYPE_STRING; - bind[i].buffer= (char *)my_malloc(max_length, MYF(MY_WME | MY_FAE)); - bind[i].buffer_length= max_length; - bind[i].is_null= &is_null[i]; - bind[i].length= &length[i]; + my_bind[i].buffer_type= MYSQL_TYPE_STRING; + my_bind[i].buffer= (char *)my_malloc(max_length, MYF(MY_WME | MY_FAE)); + my_bind[i].buffer_length= max_length; + my_bind[i].is_null= &is_null[i]; + my_bind[i].length= &length[i]; DBUG_PRINT("bind", ("col[%d]: buffer_type: %d, buffer_length: %lu", - i, bind[i].buffer_type, bind[i].buffer_length)); + i, my_bind[i].buffer_type, my_bind[i].buffer_length)); } - if (mysql_stmt_bind_result(stmt, bind)) + if (mysql_stmt_bind_result(stmt, my_bind)) die("mysql_stmt_bind_result failed: %d: %s", mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); while (mysql_stmt_fetch(stmt) == 0) { for (i= 0; i < num_fields; i++) - append_field(ds, i, &fields[i], (const char *) bind[i].buffer, - *bind[i].length, *bind[i].is_null); + append_field(ds, i, &fields[i], (const char *) my_bind[i].buffer, + *my_bind[i].length, *my_bind[i].is_null); if (!display_result_vertically) dynstr_append_mem(ds, "\n", 1); } @@ -4509,10 +4504,10 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, for (i= 0; i < num_fields; i++) { /* Free data for output */ - my_free((gptr)bind[i].buffer, MYF(MY_WME | MY_FAE)); + my_free((gptr)my_bind[i].buffer, MYF(MY_WME | MY_FAE)); } /* Free array with bind structs, lengths and NULL flags */ - my_free((gptr)bind , MYF(MY_WME | MY_FAE)); + my_free((gptr)my_bind , MYF(MY_WME | MY_FAE)); my_free((gptr)length , MYF(MY_WME | MY_FAE)); my_free((gptr)is_null , MYF(MY_WME | MY_FAE)); } @@ -4649,17 +4644,14 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql) /* Run query using MySQL C API - SYNPOSIS - run_query_normal - mysql - mysql handle - command - currrent command pointer - flags -flags indicating wheter to SEND and/or REAP - query - query string to execute - query_len - length query string to execute - ds - output buffer wherte to store result form query - - RETURN VALUE - error - function will not return + SYNOPSIS + run_query_normal() + mysql mysql handle + command current command pointer + flags flags indicating if we should SEND and/or REAP + query query string to execute + query_len length query string to execute + ds output buffer where to store result form query */ void run_query_normal(struct st_connection *cn, struct st_command *command, @@ -5184,15 +5176,14 @@ int util_query(MYSQL* org_mysql, const char* query){ /* Run query + SYNPOSIS + run_query() + mysql mysql handle + command currrent command pointer + flags control the phased/stages of query execution to be performed if QUERY_SEND_FLAG bit is on, the query will be sent. If QUERY_REAP_FLAG is on the result will be read - for regular query, both bits must be on - - SYNPOSIS - run_query - mysql - mysql handle - command - currrent command pointer - */ void run_query(struct st_connection *cn, struct st_command *command, int flags) @@ -5207,6 +5198,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) my_bool view_created= 0, sp_created= 0; my_bool complete_query= ((flags & QUERY_SEND_FLAG) && (flags & QUERY_REAP_FLAG)); + DBUG_ENTER("run_query"); init_dynamic_string(&ds_warnings, NULL, 0, 256); @@ -5372,7 +5364,6 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) if (command->require_file[0]) { - /* A result file was specified for _this_ query and the output should be checked against an already existing file which has been specified using --require or --result @@ -5385,6 +5376,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) dynstr_free(&ds_result); if (command->type == Q_EVAL) dynstr_free(&eval_query); + DBUG_VOID_RETURN; } /****************************************************************************/ @@ -5712,8 +5704,8 @@ int main(int argc, char **argv) if (!(cur_con->name = my_strdup("default", MYF(MY_WME)))) die("Out of memory"); - safe_connect(&cur_con->mysql, cur_con->name, host, user, pass, - db, port, unix_sock); + safe_connect(&cur_con->mysql, cur_con->name, opt_host, opt_user, opt_pass, + opt_db, opt_port, unix_sock); /* Use all time until exit if no explicit 'start_timer' */ timer_start= timer_now(); @@ -6080,8 +6072,6 @@ int main(int argc, char **argv) if (result_file_name && ds_warning_messages.length) dump_warning_messages(); - dynstr_free(&ds_res); - timer_output(); free_used_memory(); my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR); diff --git a/client/sql_string.cc b/client/sql_string.cc index 7d7d5d70754..9d887ff031c 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -247,6 +247,10 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs) 0 No conversion needed 1 Either character set conversion or adding leading zeros (e.g. for UCS-2) must be done + + NOTE + to_cs may be NULL for "no conversion" if the system variable + character_set_results is NULL. */ bool String::needs_conversion(uint32 arg_length, @@ -255,7 +259,8 @@ bool String::needs_conversion(uint32 arg_length, uint32 *offset) { *offset= 0; - if ((to_cs == &my_charset_bin) || + if (!to_cs || + (to_cs == &my_charset_bin) || (to_cs == from_cs) || my_charset_same(from_cs, to_cs) || ((from_cs == &my_charset_bin) && @@ -612,27 +617,26 @@ skip: } /* -** replace substring with string -** If wrong parameter or not enough memory, do nothing + Replace substring with string + If wrong parameter or not enough memory, do nothing */ - bool String::replace(uint32 offset,uint32 arg_length,const String &to) { return replace(offset,arg_length,to.ptr(),to.length()); } bool String::replace(uint32 offset,uint32 arg_length, - const char *to,uint32 length) + const char *to, uint32 to_length) { - long diff = (long) length-(long) arg_length; + long diff = (long) to_length-(long) arg_length; if (offset+arg_length <= str_length) { if (diff < 0) { - if (length) - memcpy(Ptr+offset,to,length); - bmove(Ptr+offset+length,Ptr+offset+arg_length, + if (to_length) + memcpy(Ptr+offset,to,to_length); + bmove(Ptr+offset+to_length,Ptr+offset+arg_length, str_length-offset-arg_length); } else @@ -644,8 +648,8 @@ bool String::replace(uint32 offset,uint32 arg_length, bmove_upp(Ptr+str_length+diff,Ptr+str_length, str_length-offset-arg_length); } - if (length) - memcpy(Ptr+offset,to,length); + if (to_length) + memcpy(Ptr+offset,to,to_length); } str_length+=(uint32) diff; } @@ -818,8 +822,18 @@ copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs, from++; wc= '?'; } + else if (cnvres > MY_CS_TOOSMALL) + { + /* + A correct multibyte sequence detected + But it doesn't have Unicode mapping. + */ + error_count++; + from+= (-cnvres); + wc= '?'; + } else - break; // Impossible char. + break; // Not enough characters outp: if ((cnvres= (*wc_mb)(to_cs, wc, (uchar*) to, to_end)) > 0) @@ -847,22 +861,22 @@ void String::print(String *str) switch (c) { case '\\': - str->append("\\\\", 2); + str->append(STRING_WITH_LEN("\\\\")); break; case '\0': - str->append("\\0", 2); + str->append(STRING_WITH_LEN("\\0")); break; case '\'': - str->append("\\'", 2); + str->append(STRING_WITH_LEN("\\'")); break; case '\n': - str->append("\\n", 2); + str->append(STRING_WITH_LEN("\\n")); break; case '\r': - str->append("\\r", 2); + str->append(STRING_WITH_LEN("\\r")); break; case 26: //Ctrl-Z - str->append("\\z", 2); + str->append(STRING_WITH_LEN("\\z")); break; default: str->append(c); diff --git a/client/sql_string.h b/client/sql_string.h index 0e0d2452297..a74fbf58082 100644 --- a/client/sql_string.h +++ b/client/sql_string.h @@ -23,6 +23,8 @@ #define NOT_FIXED_DEC 31 #endif +#define STRING_WITH_LEN(X) ((const char*) X), ((uint) (sizeof(X) - 1)) + class String; int sortcmp(const String *a,const String *b, CHARSET_INFO *cs); String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); @@ -76,13 +78,15 @@ public: { /* never called */ } ~String() { free(); } - inline void set_charset(CHARSET_INFO *charset) { str_charset= charset; } + inline void set_charset(CHARSET_INFO *charset_arg) + { str_charset= charset_arg; } inline CHARSET_INFO *charset() const { return str_charset; } inline uint32 length() const { return str_length;} inline uint32 alloced_length() const { return Alloced_length;} inline char& operator [] (uint32 i) const { return Ptr[i]; } inline void length(uint32 len) { str_length=len ; } inline bool is_empty() { return (str_length == 0); } + inline void mark_as_const() { Alloced_length= 0;} inline const char *ptr() const { return Ptr; } inline char *c_ptr() { |