diff options
author | Sergei Golubchik <sergii@pisem.net> | 2011-10-19 21:45:18 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2011-10-19 21:45:18 +0200 |
commit | 76f0b94bb0b2994d639353530c5b251d0f1a204b (patch) | |
tree | 9ed50628aac34f89a37637bab2fc4915b86b5eb4 /client | |
parent | 4e46d8e5bff140f2549841167dc4b65a3c0a645d (diff) | |
parent | 5dc1a2231f55bacc9aaf0e24816f3d9c2ee1f21d (diff) | |
download | mariadb-git-76f0b94bb0b2994d639353530c5b251d0f1a204b.tar.gz |
merge with 5.3
sql/sql_insert.cc:
CREATE ... IF NOT EXISTS may do nothing, but
it is still not a failure. don't forget to my_ok it.
******
CREATE ... IF NOT EXISTS may do nothing, but
it is still not a failure. don't forget to my_ok it.
sql/sql_table.cc:
small cleanup
******
small cleanup
Diffstat (limited to 'client')
-rw-r--r-- | client/client_priv.h | 3 | ||||
-rw-r--r-- | client/mysql.cc | 61 | ||||
-rw-r--r-- | client/mysql_upgrade.c | 6 | ||||
-rw-r--r-- | client/mysqladmin.cc | 3 | ||||
-rw-r--r-- | client/mysqlbinlog.cc | 205 | ||||
-rw-r--r-- | client/mysqlcheck.c | 32 | ||||
-rw-r--r-- | client/mysqldump.c | 138 | ||||
-rw-r--r-- | client/mysqlimport.c | 3 | ||||
-rw-r--r-- | client/mysqlshow.c | 3 | ||||
-rw-r--r-- | client/mysqlslap.c | 19 | ||||
-rw-r--r-- | client/mysqltest.cc | 247 | ||||
-rw-r--r-- | client/readline.cc | 3 | ||||
-rw-r--r-- | client/sql_string.cc | 6 | ||||
-rw-r--r-- | client/sql_string.h | 8 |
14 files changed, 559 insertions, 178 deletions
diff --git a/client/client_priv.h b/client/client_priv.h index 0eed5262260..d6fe90b2644 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -50,6 +50,7 @@ enum options_client OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_SERVER_ARG, OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME, OPT_SIGINT_IGNORE, OPT_HEXBLOB, OPT_ORDER_BY_PRIMARY, OPT_COUNT, + OPT_FLUSH_TABLES, OPT_TRIGGERS, OPT_MYSQL_ONLY_PRINT, OPT_MYSQL_LOCK_DIRECTORY, @@ -86,6 +87,8 @@ enum options_client OPT_DEFAULT_AUTH, OPT_ABORT_SOURCE_ON_ERROR, OPT_REWRITE_DB, + OPT_REPORT_PROGRESS, + OPT_SKIP_ANNOTATE_ROWS_EVENTS, OPT_MAX_CLIENT_OPTION /* should be always the last */ }; diff --git a/client/mysql.cc b/client/mysql.cc index d87ca257b11..b66b4263f54 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1,5 +1,5 @@ /* Copyright (C) 2000-2009 MySQL AB - Copyright 2000, 2010, Oracle and/or its affiliates. All rights reserved. + Copyright 2000, 2010, Oracle and/or its affiliates. Copyright 2000-2010 Monty Program Ab This program is free software; you can redistribute it and/or modify @@ -45,7 +45,7 @@ #include <locale.h> #endif -const char *VER= "14.16"; +const char *VER= "15.0"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 @@ -142,7 +142,7 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0, default_pager_set= 0, opt_sigint_ignore= 0, auto_vertical_output= 0, show_warnings= 0, executing_query= 0, - ignore_spaces= 0; + ignore_spaces= 0, opt_progress_reports; static my_bool debug_info_flag, debug_check_flag, batch_abort_on_error; static my_bool column_types_flag; static my_bool preserve_comments= 0; @@ -242,6 +242,13 @@ static void init_username(); static void add_int_to_prompt(int toadd); static int get_result_width(MYSQL_RES *res); static int get_field_disp_length(MYSQL_FIELD * field); +#ifndef EMBEDDED_LIBRARY +static uint last_progress_report_length= 0; +static void report_progress(const MYSQL *mysql, uint stage, uint max_stage, + double progress, const char *proc_info, + uint proc_info_length); +#endif +static void report_progress_end(); /* A structure which contains information on the commands this program can understand. */ @@ -1018,7 +1025,8 @@ static COMMANDS commands[] = { { (char *)NULL, 0, 0, 0, ""} }; -static const char *load_default_groups[]= { "mysql","client",0 }; +static const char *load_default_groups[]= +{ "mysql", "client", "client-server", "client-mariadb", 0 }; static int embedded_server_arg_count= 0; static char *embedded_server_args[MAX_SERVER_ARGS]; @@ -1500,6 +1508,10 @@ static struct my_option my_long_options[] = "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").", &opt_mysql_port, &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"progress-reports", OPT_REPORT_PROGRESS, + "Get progress reports for long running commands (like ALTER TABLE)", + &opt_progress_reports, &opt_progress_reports, 0, GET_BOOL, NO_ARG, 1, 0, + 0, 0, 0, 0}, {"prompt", OPT_PROMPT, "Set the mysql prompt to this value.", ¤t_prompt, ¤t_prompt, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -1821,6 +1833,7 @@ static int get_options(int argc, char **argv) opt_outfile= 0; opt_reconnect= 0; connect_flag= 0; /* Not in interactive mode */ + opt_progress_reports= 0; } if (argc > 1) @@ -1844,6 +1857,9 @@ static int get_options(int argc, char **argv) if (ignore_spaces) connect_flag|= CLIENT_IGNORE_SPACE; + if (opt_progress_reports) + connect_flag|= CLIENT_PROGRESS; + return(0); } @@ -3005,6 +3021,7 @@ com_go(String *buffer,char *line __attribute__((unused))) timer=start_timer(); executing_query= 1; error= mysql_real_query_for_lazy(buffer->ptr(),buffer->length()); + report_progress_end(); #ifdef HAVE_READLINE if (status.add_to_history) @@ -4425,6 +4442,13 @@ sql_real_connect(char *host,char *database,char *user,char *password, connected=1; #ifndef EMBEDDED_LIBRARY mysql.reconnect= debug_info_flag; // We want to know if this happens + + /* + CLIENT_PROGRESS is set only if we requsted it in mysql_real_connect() + and the server also supports it + */ + if (mysql.client_flag & CLIENT_PROGRESS) + mysql_options(&mysql, MYSQL_PROGRESS_CALLBACK, (void*) report_progress); #else mysql.reconnect= 1; #endif @@ -5056,3 +5080,32 @@ static int com_prompt(String *buffer __attribute__((unused)), tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt); return 0; } + +#ifndef EMBEDDED_LIBRARY +static void report_progress(const MYSQL *mysql, uint stage, uint max_stage, + double progress, const char *proc_info, + uint proc_info_length) +{ + uint length= printf("Stage: %d of %d '%.*s' %6.3g%% of stage done", + stage, max_stage, proc_info_length, proc_info, + progress); + if (length < last_progress_report_length) + printf("%*s", last_progress_report_length - length, ""); + putc('\r', stdout); + fflush(stdout); + last_progress_report_length= length; +} + +static void report_progress_end() +{ + if (last_progress_report_length) + { + printf("%*s\r", last_progress_report_length, ""); + last_progress_report_length= 0; + } +} +#else +static void report_progress_end() +{ +} +#endif diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index a1d3af46acb..73acc241912 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -839,8 +839,10 @@ static int run_sql_fix_privilege_tables(void) static const char *load_default_groups[]= { - "client", /* Read settings how to connect to server */ - "mysql_upgrade", /* Read special settings for mysql_upgrade*/ + "client", /* Read settings how to connect to server */ + "mysql_upgrade", /* Read special settings for mysql_upgrade */ + "client-server", /* Reads settings common between client & server */ + "client-mariadb", /* Read mariadb unique client settings */ 0 }; diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 89287617b32..4335acdfb9c 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -222,7 +222,8 @@ static struct my_option my_long_options[] = }; -static const char *load_default_groups[]= { "mysqladmin","client",0 }; +static const char *load_default_groups[]= +{ "mysqladmin", "client", "client-server", "client-mariadb", 0 }; my_bool get_one_option(int optid, const struct my_option *opt __attribute__((unused)), diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 14a9cc6556b..e5af12bf49a 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -68,7 +68,8 @@ static FILE *result_file; #ifndef DBUG_OFF static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace"; #endif -static const char *load_groups[]= { "mysqlbinlog","client",0 }; +static const char *load_groups[]= +{ "mysqlbinlog", "client", "client-server", "client-mariadb", 0 }; static void error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); static void warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); @@ -86,6 +87,7 @@ static char* database= 0; static my_bool force_opt= 0, short_form= 0, remote_opt= 0; static my_bool debug_info_flag, debug_check_flag; static my_bool force_if_open_opt= 1; +static my_bool opt_verify_binlog_checksum= 1; static ulonglong offset = 0; static char* host = 0; static int port= 0; @@ -111,7 +113,8 @@ static my_time_t start_datetime= 0, stop_datetime= MY_TIME_T_MAX; static ulonglong rec_count= 0; static short binlog_flags = 0; static MYSQL* mysql = NULL; -static char* dirname_for_local_load= 0; +static const char* dirname_for_local_load= 0; +static bool opt_skip_annotate_rows_events= 0; /** Pointer to the Format_description_log_event of the currently active binlog. @@ -133,6 +136,71 @@ enum Exit_status { OK_STOP }; +/** + Pointer to the last read Annotate_rows_log_event. Having read an + Annotate_rows event, we should not print it immediatedly because all + subsequent rbr events can be filtered away, and have to keep it for a while. + Also because of that when reading a remote Annotate event we have to keep + its binary log representation in a separately allocated buffer. +*/ +static Annotate_rows_log_event *annotate_event= NULL; + +void free_annotate_event() +{ + if (annotate_event) + { + delete annotate_event; + annotate_event= 0; + } +} + +Log_event* read_remote_annotate_event(uchar* net_buf, ulong event_len, + const char **error_msg) +{ + uchar *event_buf; + Log_event* event; + + if (!(event_buf= (uchar*) my_malloc(event_len + 1, MYF(MY_WME)))) + { + error("Out of memory"); + return 0; + } + + memcpy(event_buf, net_buf, event_len); + event_buf[event_len]= 0; + + if (!(event= Log_event::read_log_event((const char*) event_buf, event_len, + error_msg, glob_description_event, + opt_verify_binlog_checksum))) + { + my_free(event_buf); + return 0; + } + /* + Ensure the event->temp_buf is pointing to the allocated buffer. + (TRUE = free temp_buf on the event deletion) + */ + event->register_temp_buf((char*)event_buf, TRUE); + + return event; +} + +void keep_annotate_event(Annotate_rows_log_event* event) +{ + free_annotate_event(); + annotate_event= event; +} + +void print_annotate_event(PRINT_EVENT_INFO *print_event_info) +{ + if (annotate_event) + { + annotate_event->print(result_file, print_event_info); + delete annotate_event; // the event should not be printed more than once + annotate_event= 0; + } +} + static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, const char* logname); static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, @@ -648,11 +716,16 @@ static bool shall_skip_database(const char *log_dbname) producing USE statements by corresponding log event print-functions. */ -void print_use_stmt(PRINT_EVENT_INFO* pinfo, const char* db, size_t db_len) +static void +print_use_stmt(PRINT_EVENT_INFO* pinfo, const Query_log_event *ev) { + const char* db= ev->db; + const size_t db_len= ev->db_len; + // pinfo->db is the current db. // If current db is the same as required db, do nothing. - if (!db || !memcmp(pinfo->db, db, db_len + 1)) + if ((ev->flags & LOG_EVENT_SUPPRESS_USE_F) || !db || + !memcmp(pinfo->db, db, db_len + 1)) return; // Current db and required db are different. @@ -750,7 +823,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, read them to be able to process the wanted events. */ if (((rec_count >= offset) && - ((my_time_t)(ev->when) >= start_datetime)) || + (ev->when >= start_datetime)) || (ev_type == FORMAT_DESCRIPTION_EVENT)) { if (ev_type != FORMAT_DESCRIPTION_EVENT) @@ -774,7 +847,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, server_id && (server_id != ev->server_id)) goto end; } - if (((my_time_t)(ev->when) >= stop_datetime) + if ((ev->when >= stop_datetime) || (pos >= stop_position_mot)) { /* end the program */ @@ -797,9 +870,20 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, case QUERY_EVENT: { Query_log_event *qe= (Query_log_event*)ev; - if (!qe->is_trans_keyword() && shall_skip_database(qe->db)) - goto end; - print_use_stmt(print_event_info, qe->db, qe->db_len); + if (!qe->is_trans_keyword()) + { + if (shall_skip_database(qe->db)) + goto end; + } + else + { + /* + In case the event for one of these statements is obtained + from binary log 5.0, make it compatible with 5.1 + */ + qe->flags|= LOG_EVENT_SUPPRESS_USE_F; + } + print_use_stmt(print_event_info, qe); if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) { if ((retval= write_event_header_and_base64(ev, result_file, @@ -938,7 +1022,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, if (!shall_skip_database(exlq->db)) { - print_use_stmt(print_event_info, exlq->db, exlq->db_len); + print_use_stmt(print_event_info, exlq); if (fname) { convert_path_to_forward_slashes(fname); @@ -953,6 +1037,19 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, my_free(fname); break; } + case ANNOTATE_ROWS_EVENT: + if (!opt_skip_annotate_rows_events) + { + /* + We don't print Annotate event just now because all subsequent + rbr-events can be filtered away. Instead we'll keep the event + till it will be printed together with the first not filtered + away Table map or the last rbr will be processed. + */ + keep_annotate_event((Annotate_rows_log_event*) ev); + destroy_evt= FALSE; + } + break; case TABLE_MAP_EVENT: { Table_map_log_event *map= ((Table_map_log_event *)ev); @@ -962,6 +1059,13 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, destroy_evt= FALSE; goto end; } + /* + The Table map is to be printed, so it's just the time when we may + print the kept Annotate event (if there is any). + print_annotate_event() also deletes the kept Annotate event. + */ + print_annotate_event(print_event_info); + size_t len_to= 0; const char* db_to= binlog_filter->get_rewrite_db(map->get_db_name(), &len_to); if (len_to && map->rewrite_db(db_to, len_to, glob_description_event)) @@ -998,6 +1102,13 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, if (print_event_info->m_table_map_ignored.count() > 0) print_event_info->m_table_map_ignored.clear_tables(); + /* + If there is a kept Annotate event and all corresponding + rbr-events were filtered away, the Annotate event was not + freed and it is just the time to do it. + */ + free_annotate_event(); + /* One needs to take into account an event that gets filtered but was last event in the statement. If this is @@ -1228,10 +1339,18 @@ that may lead to an endless loop.", "Used to reserve file descriptors for use by this program.", &open_files_limit, &open_files_limit, 0, GET_ULONG, REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0}, + {"verify-binlog-checksum", 'c', "Verify checksum binlog events.", + (uchar**) &opt_verify_binlog_checksum, (uchar**) &opt_verify_binlog_checksum, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"rewrite-db", OPT_REWRITE_DB, "Updates to a database with a different name than the original. \ Example: rewrite-db='from->to'.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"skip-annotate-rows-events", OPT_SKIP_ANNOTATE_ROWS_EVENTS, + "Don't print Annotate_rows events stored in the binary log.", + (uchar**) &opt_skip_annotate_rows_events, + (uchar**) &opt_skip_annotate_rows_events, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -1307,7 +1426,7 @@ static void cleanup() my_free(database); my_free(host); my_free(user); - my_free(dirname_for_local_load); + my_free(const_cast<char*>(dirname_for_local_load)); delete glob_description_event; if (mysql) @@ -1339,7 +1458,7 @@ static my_time_t convert_str_to_timestamp(const char* str) int was_cut; MYSQL_TIME l_time; long dummy_my_timezone; - my_bool dummy_in_dst_time_gap; + uint dummy_in_dst_time_gap; /* We require a total specification (date AND time) */ if (str_to_datetime(str, (uint) strlen(str), &l_time, 0, &was_cut) != MYSQL_TIMESTAMP_DATETIME || was_cut) @@ -1503,7 +1622,7 @@ static int parse_args(int *argc, char*** argv) */ static Exit_status safe_connect() { - /* Close and old connections to MySQL */ + /* Close any old connections to MySQL */ if (mysql) mysql_close(mysql); @@ -1613,7 +1732,18 @@ static Exit_status check_master_version() "Master reported NULL for the version."); goto err; } - + /* + Make a notice to the server that this client + is checksum-aware. It does not need the first fake Rotate + necessary checksummed. + That preference is specified below. + */ + if (mysql_query(mysql, "SET @master_binlog_checksum='NONE'")) + { + error("Could not notify master about checksum awareness." + "Master returned '%s'", mysql_error(mysql)); + goto err; + } delete glob_description_event; switch (*version) { case '3': @@ -1695,6 +1825,8 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, cast to uint32. */ int4store(buf, (uint32)start_position); + if (!opt_skip_annotate_rows_events) + binlog_flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT; int2store(buf + BIN_LOG_HEADER_SIZE, binlog_flags); size_t tlen = strlen(logname); @@ -1727,18 +1859,31 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, break; // end of data DBUG_PRINT("info",( "len: %lu net->read_pos[5]: %d\n", len, net->read_pos[5])); - if (!(ev= Log_event::read_log_event((const char*) net->read_pos + 1 , - len - 1, &error_msg, - glob_description_event))) + if (net->read_pos[5] == ANNOTATE_ROWS_EVENT) { - error("Could not construct log event object: %s", error_msg); - DBUG_RETURN(ERROR_STOP); - } - /* - If reading from a remote host, ensure the temp_buf for the - Log_event class is pointing to the incoming stream. - */ - ev->register_temp_buf((char *) net->read_pos + 1, FALSE); + if (!(ev= read_remote_annotate_event(net->read_pos + 1, len - 1, + &error_msg))) + { + error("Could not construct annotate event object: %s", error_msg); + DBUG_RETURN(ERROR_STOP); + } + } + else + { + if (!(ev= Log_event::read_log_event((const char*) net->read_pos + 1 , + len - 1, &error_msg, + glob_description_event, + opt_verify_binlog_checksum))) + { + error("Could not construct log event object: %s", error_msg); + DBUG_RETURN(ERROR_STOP); + } + /* + If reading from a remote host, ensure the temp_buf for the + Log_event class is pointing to the incoming stream. + */ + ev->register_temp_buf((char *) net->read_pos + 1, FALSE); + } Log_event_type type= ev->get_type_code(); if (glob_description_event->binlog_version >= 3 || @@ -1956,7 +2101,8 @@ static Exit_status check_header(IO_CACHE* file, Format_description_log_event *new_description_event; my_b_seek(file, tmp_pos); /* seek back to event's start */ if (!(new_description_event= (Format_description_log_event*) - Log_event::read_log_event(file, glob_description_event))) + Log_event::read_log_event(file, glob_description_event, + opt_verify_binlog_checksum))) /* EOF can't be hit here normally, so it's a real error */ { error("Could not read a Format_description_log_event event at " @@ -1989,7 +2135,8 @@ static Exit_status check_header(IO_CACHE* file, { Log_event *ev; my_b_seek(file, tmp_pos); /* seek back to event's start */ - if (!(ev= Log_event::read_log_event(file, glob_description_event))) + if (!(ev= Log_event::read_log_event(file, glob_description_event, + opt_verify_binlog_checksum))) { /* EOF can't be hit here normally, so it's a real error */ error("Could not read a Rotate_log_event event at offset %llu;" @@ -2102,7 +2249,8 @@ static Exit_status 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, glob_description_event); + Log_event* ev = Log_event::read_log_event(file, glob_description_event, + opt_verify_binlog_checksum); if (!ev) { /* @@ -2256,6 +2404,7 @@ int main(int argc, char** argv) if (result_file != stdout) my_fclose(result_file, MYF(0)); cleanup(); + free_annotate_event(); delete binlog_filter; free_root(&s_mem_root, MYF(0)); free_defaults(defaults_argv); diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 8139c373f2c..9fea9356e4c 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -16,7 +16,7 @@ /* By Jani Tolonen, 2001-04-20, MySQL Development Team */ -#define CHECK_VERSION "2.6.0" +#define CHECK_VERSION "2.7.0" #include "client_priv.h" #include <m_ctype.h> @@ -36,8 +36,8 @@ static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 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, 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; + opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0; +static my_bool opt_write_binlog= 1, opt_flush_tables= 0; static uint verbose = 0, opt_mysql_port=0; static int my_end_arg; static char * opt_mysql_unix_port = 0; @@ -123,6 +123,9 @@ static struct my_option my_long_options[] = "If you are using this option with CHECK TABLE, it will ensure that the table is 100 percent consistent, but will take a long time. If you are using this option with REPAIR TABLE, it will force using old slow repair with keycache method, instead of much faster repair by sorting.", &opt_extended, &opt_extended, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"flush", OPT_FLUSH_TABLES, "Flush each table after check. This is useful if you don't want to have the checked tables take up space in the caches after the check", + &opt_flush_tables, &opt_flush_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0 }, {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host",'h', "Connect to host.", ¤t_host, @@ -192,7 +195,8 @@ static struct my_option my_long_options[] = {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; -static const char *load_default_groups[] = { "mysqlcheck", "client", 0 }; +static const char *load_default_groups[]= +{ "mysqlcheck", "client", "client-server", "client-mariadb", 0 }; static void print_version(void); @@ -740,6 +744,7 @@ static int disable_binlog() static int handle_request_for_tables(char *tables, uint length) { char *query, *end, options[100], message[100]; + char table_name_buff[NAME_CHAR_LEN*2*2+1], *table_name; uint query_length= 0; const char *op = 0; DBUG_ENTER("handle_request_for_tables"); @@ -778,13 +783,17 @@ static int handle_request_for_tables(char *tables, uint length) { /* No backticks here as we added them before */ query_length= sprintf(query, "%s TABLE %s %s", op, tables, options); + table_name= tables; } else { - char *ptr; + char *ptr, *org; - ptr= strmov(strmov(query, op), " TABLE "); + org= ptr= strmov(strmov(query, op), " TABLE "); ptr= fix_table_name(ptr, tables); + strmake(table_name_buff, org, min((int) sizeof(table_name_buff)-1, + (int) (ptr - org))); + table_name= table_name_buff; ptr= strxmov(ptr, " ", options, NullS); query_length= (uint) (ptr - query); } @@ -792,9 +801,20 @@ static int handle_request_for_tables(char *tables, uint length) { sprintf(message, "when executing '%s TABLE ... %s'", op, options); DBerror(sock, message); + my_free(query); DBUG_RETURN(1); } print_result(); + if (opt_flush_tables) + { + query_length= sprintf(query, "FLUSH TABLES %s", table_name); + if (mysql_real_query(sock, query, query_length)) + { + DBerror(sock, query); + my_free(query); + DBUG_RETURN(1); + } + } my_free(query); DBUG_RETURN(0); } diff --git a/client/mysqldump.c b/client/mysqldump.c index 41b3fb2219d..4103d8ccb04 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.13" +#define DUMP_VERSION "10.14" #include <my_global.h> #include <my_sys.h> @@ -78,6 +78,9 @@ #define IGNORE_DATA 0x01 /* don't dump data for this table */ #define IGNORE_INSERT_DELAYED 0x02 /* table doesn't support INSERT DELAYED */ +/* Chars needed to store LONGLONG, excluding trailing '\0'. */ +#define LONGLONG_LEN 20 + static void add_load_option(DYNAMIC_STRING *str, const char *option, const char *option_value); static ulong find_set(TYPELIB *lib, const char *x, uint length, @@ -368,9 +371,9 @@ static struct my_option my_long_options[] = "This causes the binary log position and filename to be appended to the " "output. If equal to 1, will print it as a CHANGE MASTER command; if equal" " to 2, that command will be prefixed with a comment symbol. " - "This option will turn --lock-all-tables on, unless " - "--single-transaction is specified too (in which case a " - "global read lock is only taken a short time at the beginning of the dump; " + "This option will turn --lock-all-tables on, unless --single-transaction " + "is specified too (on servers before MariaDB 5.3 this will still take a " + "global read lock for a short time at the beginning of the dump; " "don't forget to read about --single-transaction below). In all cases, " "any action on logs will happen at the exact moment of the dump. " "Option automatically turns --lock-tables off.", @@ -510,7 +513,8 @@ static struct my_option my_long_options[] = {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; -static const char *load_default_groups[]= { "mysqldump","client",0 }; +static const char *load_default_groups[]= +{ "mysqldump", "client", "client-server", "client-mariadb", 0 }; static void maybe_exit(int error); static void die(int error, const char* reason, ...); @@ -655,8 +659,13 @@ static void write_header(FILE *sql_file, char *db_name) if (!path) { + if (!opt_no_create_info) + { + /* We don't need unique checks as the table is created just before */ + fprintf(md_result_file,"\ +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\n"); + } fprintf(md_result_file,"\ -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\n\ /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;\n\ "); } @@ -686,8 +695,12 @@ static void write_footer(FILE *sql_file) if (!path) { fprintf(md_result_file,"\ -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;\n\ +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;\n"); + if (!opt_no_create_info) + { + fprintf(md_result_file,"\ /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;\n"); + } } if (opt_set_charset) fprintf(sql_file, @@ -1128,6 +1141,44 @@ static int fetch_db_collation(const char *db_name, } +/* + Check if server supports non-blocking binlog position using the + binlog_snapshot_file and binlog_snapshot_position status variables. If it + does, also return the position obtained if output pointers are non-NULL. + Returns 1 if position available, 0 if not. +*/ +static int +check_consistent_binlog_pos(char *binlog_pos_file, char *binlog_pos_offset) +{ + MYSQL_RES *res; + MYSQL_ROW row; + int found; + + if (mysql_query_with_error_report(mysql, &res, + "SHOW STATUS LIKE 'binlog_snapshot_%'")) + return 1; + + found= 0; + while ((row= mysql_fetch_row(res))) + { + if (0 == strcmp(row[0], "binlog_snapshot_file")) + { + if (binlog_pos_file) + strmake(binlog_pos_file, row[1], FN_REFLEN-1); + found++; + } + else if (0 == strcmp(row[0], "binlog_snapshot_position")) + { + if (binlog_pos_offset) + strmake(binlog_pos_offset, row[1], LONGLONG_LEN); + found++; + } + } + mysql_free_result(res); + + return (found == 2); +} + static char *my_case_str(const char *str, uint str_len, const char *token, @@ -4369,42 +4420,65 @@ static int dump_selected_tables(char *db, char **table_names, int tables) } /* dump_selected_tables */ -static int do_show_master_status(MYSQL *mysql_con) +static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos) { MYSQL_ROW row; MYSQL_RES *master; + char binlog_pos_file[FN_REFLEN]; + char binlog_pos_offset[LONGLONG_LEN+1]; + char *file, *offset; const char *comment_prefix= (opt_master_data == MYSQL_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : ""; - if (mysql_query_with_error_report(mysql_con, &master, "SHOW MASTER STATUS")) + + if (consistent_binlog_pos) { - return 1; + if(!check_consistent_binlog_pos(binlog_pos_file, binlog_pos_offset)) + return 1; + file= binlog_pos_file; + offset= binlog_pos_offset; } else { + if (mysql_query_with_error_report(mysql_con, &master, "SHOW MASTER STATUS")) + return 1; + row= mysql_fetch_row(master); if (row && row[0] && row[1]) { - /* SHOW MASTER STATUS reports file and position */ - if (opt_comments) - fprintf(md_result_file, - "\n--\n-- Position to start replication or point-in-time " - "recovery from\n--\n\n"); - fprintf(md_result_file, - "%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", - comment_prefix, row[0], row[1]); - check_io(md_result_file); + file= row[0]; + offset= row[1]; } - else if (!ignore_errors) + else { - /* SHOW MASTER STATUS reports nothing and --force is not enabled */ - my_printf_error(0, "Error: Binlogging on server not active", - MYF(0)); mysql_free_result(master); - maybe_exit(EX_MYSQLERR); - return 1; + if (!ignore_errors) + { + /* SHOW MASTER STATUS reports nothing and --force is not enabled */ + my_printf_error(0, "Error: Binlogging on server not active", + MYF(0)); + maybe_exit(EX_MYSQLERR); + return 1; + } + else + { + return 0; + } } - mysql_free_result(master); } + + /* SHOW MASTER STATUS reports file and position */ + if (opt_comments) + fprintf(md_result_file, + "\n--\n-- Position to start replication or point-in-time " + "recovery from\n--\n\n"); + fprintf(md_result_file, + "%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", + comment_prefix, file, offset); + check_io(md_result_file); + + if (!consistent_binlog_pos) + mysql_free_result(master); + return 0; } @@ -5167,6 +5241,7 @@ int main(int argc, char **argv) { char bin_log_name[FN_REFLEN]; int exit_code; + int consistent_binlog_pos= 0; MY_INIT("mysqldump"); compatible_mode_normal_str[0]= 0; @@ -5200,7 +5275,13 @@ int main(int argc, char **argv) if (opt_slave_data && do_stop_slave_sql(mysql)) goto err; - if ((opt_lock_all_tables || opt_master_data) && + if (opt_single_transaction && opt_master_data) + { + /* See if we can avoid FLUSH TABLES WITH READ LOCK (MariaDB 5.3+). */ + consistent_binlog_pos= check_consistent_binlog_pos(NULL, NULL); + } + + if ((opt_lock_all_tables || (opt_master_data && !consistent_binlog_pos)) && do_flush_tables_read_lock(mysql)) goto err; if (opt_single_transaction && start_transaction(mysql)) @@ -5218,10 +5299,11 @@ int main(int argc, char **argv) goto err; flush_logs= 0; /* not anymore; that would not be sensible */ } + /* Add 'STOP SLAVE to beginning of dump */ if (opt_slave_apply && add_stop_slave()) goto err; - if (opt_master_data && do_show_master_status(mysql)) + if (opt_master_data && do_show_master_status(mysql, consistent_binlog_pos)) goto err; if (opt_slave_data && do_show_slave_status(mysql)) goto err; diff --git a/client/mysqlimport.c b/client/mysqlimport.c index e15bbdddfb9..33fd70d6316 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -188,7 +188,8 @@ static struct my_option my_long_options[] = }; -static const char *load_default_groups[]= { "mysqlimport","client",0 }; +static const char *load_default_groups[]= +{ "mysqlimport","client", "client-server", "client-mariadb", 0 }; static void print_version(void) diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 255ea3c38bb..30e2cfcc06c 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -55,7 +55,8 @@ static void print_res_header(MYSQL_RES *result); static void print_res_top(MYSQL_RES *result); static void print_res_row(MYSQL_RES *result,MYSQL_ROW cur); -static const char *load_default_groups[]= { "mysqlshow","client",0 }; +static const char *load_default_groups[]= +{ "mysqlshow","client", "client-server", "client-mariadb", 0 }; static char * opt_mysql_unix_port=0; int main(int argc, char **argv) diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 8f9f5189500..fa9a1e4d2a7 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -175,7 +175,8 @@ static uint opt_protocol= 0; static int get_options(int *argc,char ***argv); static uint opt_mysql_port= 0; -static const char *load_default_groups[]= { "mysqlslap","client",0 }; +static const char *load_default_groups[]= +{ "mysqlslap", "client", "client-server", "client-mariadb", 0 }; typedef struct statement statement; @@ -1384,9 +1385,9 @@ get_options(int *argc,char ***argv) fprintf(stderr,"%s: Could not open create file\n", my_progname); exit(1); } - tmp_string= (char *)my_malloc(sbuf.st_size + 1, + tmp_string= (char *)my_malloc((size_t)sbuf.st_size + 1, MYF(MY_ZEROFILL|MY_FAE|MY_WME)); - my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0)); + my_read(data_file, (uchar*) tmp_string, (size_t)sbuf.st_size, MYF(0)); tmp_string[sbuf.st_size]= '\0'; my_close(data_file,MYF(0)); parse_delimiter(tmp_string, &create_statements, delimiter[0]); @@ -1411,9 +1412,9 @@ get_options(int *argc,char ***argv) fprintf(stderr,"%s: Could not open query supplied file\n", my_progname); exit(1); } - tmp_string= (char *)my_malloc(sbuf.st_size + 1, + tmp_string= (char *)my_malloc((size_t)sbuf.st_size + 1, MYF(MY_ZEROFILL|MY_FAE|MY_WME)); - my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0)); + my_read(data_file, (uchar*) tmp_string, (size_t)sbuf.st_size, MYF(0)); tmp_string[sbuf.st_size]= '\0'; my_close(data_file,MYF(0)); if (user_supplied_query) @@ -1442,9 +1443,9 @@ get_options(int *argc,char ***argv) fprintf(stderr,"%s: Could not open query supplied file\n", my_progname); exit(1); } - tmp_string= (char *)my_malloc(sbuf.st_size + 1, + tmp_string= (char *)my_malloc((size_t)sbuf.st_size + 1, MYF(MY_ZEROFILL|MY_FAE|MY_WME)); - my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0)); + my_read(data_file, (uchar*) tmp_string, (size_t)sbuf.st_size, MYF(0)); tmp_string[sbuf.st_size]= '\0'; my_close(data_file,MYF(0)); if (user_supplied_pre_statements) @@ -1473,9 +1474,9 @@ get_options(int *argc,char ***argv) fprintf(stderr,"%s: Could not open query supplied file\n", my_progname); exit(1); } - tmp_string= (char *)my_malloc(sbuf.st_size + 1, + tmp_string= (char *)my_malloc((size_t)sbuf.st_size + 1, MYF(MY_ZEROFILL|MY_FAE|MY_WME)); - my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0)); + my_read(data_file, (uchar*) tmp_string, (size_t)sbuf.st_size, MYF(0)); tmp_string[sbuf.st_size]= '\0'; my_close(data_file,MYF(0)); if (user_supplied_post_statements) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 23fabcdca74..3381c4f116d 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1,4 +1,5 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. + Copyright (c) 2009-2011 Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -70,7 +71,7 @@ #define MAX_COLUMNS 256 #define MAX_EMBEDDED_SERVER_ARGS 64 #define MAX_DELIMITER_LENGTH 16 -#define DEFAULT_MAX_CONN 128 +#define DEFAULT_MAX_CONN 64 /* Flags controlling send and reap */ #define QUERY_SEND_FLAG 1 @@ -117,14 +118,15 @@ static my_bool display_result_vertically= FALSE, display_result_lower= FALSE, display_metadata= FALSE, display_result_sorted= FALSE; static my_bool disable_query_log= 0, disable_result_log= 0; static my_bool disable_connect_log= 1; -static my_bool disable_warnings= 0; +static my_bool disable_warnings= 0, disable_column_names= 0; static my_bool prepare_warnings_enabled= 0; static my_bool disable_info= 1; static my_bool abort_on_error= 1; static my_bool server_initialized= 0; static my_bool is_windows= 0; static char **default_argv; -static const char *load_default_groups[]= { "mysqltest", "client", 0 }; +static const char *load_default_groups[]= +{ "mysqltest", "client", "client-server", "client-mariadb", 0 }; static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer; static uint start_lineno= 0; /* Start line of current command */ @@ -142,6 +144,7 @@ static char TMPDIR[FN_REFLEN]; static char global_subst_from[200]; static char global_subst_to[200]; static char *global_subst= NULL; +static MEM_ROOT require_file_root; /* Block stack */ enum block_cmd { @@ -254,7 +257,7 @@ HASH var_hash; struct st_connection { - MYSQL mysql; + MYSQL *mysql; /* Used when creating views and sp, to avoid implicit commit */ MYSQL* util_mysql; char *name; @@ -308,6 +311,7 @@ enum enum_commands { Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS, Q_ENABLE_INFO, Q_DISABLE_INFO, Q_ENABLE_METADATA, Q_DISABLE_METADATA, + Q_ENABLE_COLUMN_NAMES, Q_DISABLE_COLUMN_NAMES, Q_EXEC, Q_DELIMITER, Q_DISABLE_ABORT_ON_ERROR, Q_ENABLE_ABORT_ON_ERROR, Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS, @@ -379,6 +383,8 @@ const char *command_names[]= "disable_info", "enable_metadata", "disable_metadata", + "enable_column_names", + "disable_column_names", "exec", "delimiter", "disable_abort_on_error", @@ -472,7 +478,7 @@ struct st_command int first_word_len, query_len; my_bool abort_on_error, used_replace; struct st_expected_errors expected_errors; - char require_file[FN_REFLEN]; + char *require_file; enum enum_commands type; }; @@ -611,6 +617,10 @@ public: DBUG_VOID_RETURN; DBUG_ASSERT(ds->str); +#ifdef EXTRA_DEBUG + DBUG_PRINT("QQ", ("str: %*s", (int) ds->length, ds->str)); +#endif + if (fwrite(ds->str, 1, ds->length, m_file) != ds->length) die("Failed to write %lu bytes to '%s', errno: %d", (unsigned long)ds->length, m_file_name, errno); @@ -772,10 +782,10 @@ pthread_handler_t connection_thread(void *arg) case EMB_END_CONNECTION: goto end_thread; case EMB_SEND_QUERY: - cn->result= mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len); + cn->result= mysql_send_query(cn->mysql, cn->cur_query, cn->cur_query_len); break; case EMB_READ_QUERY_RESULT: - cn->result= mysql_read_query_result(&cn->mysql); + cn->result= mysql_read_query_result(cn->mysql); break; default: DBUG_ASSERT(0); @@ -828,7 +838,7 @@ static void signal_connection_thd(struct st_connection *cn, int command) static int do_send_query(struct st_connection *cn, const char *q, int q_len) { if (!cn->has_thread) - return mysql_send_query(&cn->mysql, q, q_len); + return mysql_send_query(cn->mysql, q, q_len); cn->cur_query= q; cn->cur_query_len= q_len; signal_connection_thd(cn, EMB_SEND_QUERY); @@ -876,8 +886,8 @@ static void init_connection_thd(struct st_connection *cn) #else /*EMBEDDED_LIBRARY*/ -#define do_send_query(cn,q,q_len) mysql_send_query(&cn->mysql, q, q_len) -#define do_read_query_result(cn) mysql_read_query_result(&cn->mysql) +#define do_send_query(cn,q,q_len) mysql_send_query(cn->mysql, q, q_len) +#define do_read_query_result(cn) mysql_read_query_result(cn->mysql) #endif /*EMBEDDED_LIBRARY*/ @@ -1189,8 +1199,9 @@ void handle_command_error(struct st_command *command, uint error, int i; if (command->abort_on_error) - die("command \"%.*s\" failed with error %d. my_errno=%d", - command->first_word_len, command->query, error, my_errno); + die("command \"%.*s\" failed with error: %u my_errno: %d errno: %d", + command->first_word_len, command->query, error, my_errno, + sys_errno); i= match_expected_error(command, error, NULL); @@ -1202,8 +1213,8 @@ void handle_command_error(struct st_command *command, uint error, DBUG_VOID_RETURN; } if (command->expected_errors.count > 0) - die("command \"%.*s\" failed with wrong error: %u, errno: %d", - command->first_word_len, command->query, error, sys_errno); + die("command \"%.*s\" failed with wrong error: %u my_errno: %d errno: %d", + command->first_word_len, command->query, error, my_errno, sys_errno); } else if (command->expected_errors.err[0].type == ERR_ERRNO && command->expected_errors.err[0].code.errnum != 0) @@ -1228,7 +1239,8 @@ void close_connections() if (next_con->stmt) mysql_stmt_close(next_con->stmt); next_con->stmt= 0; - mysql_close(&next_con->mysql); + mysql_close(next_con->mysql); + next_con->mysql= 0; if (next_con->util_mysql) mysql_close(next_con->util_mysql); my_free(next_con->name); @@ -1301,24 +1313,24 @@ void free_used_memory() free_all_replace(); my_free(opt_pass); free_defaults(default_argv); + free_root(&require_file_root, MYF(0)); free_re(); #ifdef __WIN__ free_tmp_sh_file(); free_win_path_patterns(); #endif - - /* Only call mysql_server_end if mysql_server_init has been called */ - if (server_initialized) - mysql_server_end(); - - /* Don't use DBUG after mysql_server_end() */ - return; + DBUG_VOID_RETURN; } static void cleanup_and_exit(int exit_code) { free_used_memory(); + + /* Only call mysql_server_end if mysql_server_init has been called */ + if (server_initialized) + mysql_server_end(); + /* mysqltest is fundamentally written in a way that makes impossible to free all memory before exit (consider memory allocated @@ -1328,6 +1340,7 @@ static void cleanup_and_exit(int exit_code) from polluting the output. */ fclose(stderr); + my_end(my_end_arg); if (!silent) { @@ -1352,12 +1365,17 @@ static void cleanup_and_exit(int exit_code) void print_file_stack() { - for (struct st_test_file* err_file= cur_file; - err_file != file_stack; - err_file--) + struct st_test_file* err_file= cur_file; + if (err_file == file_stack) + return; + + for (;;) { + err_file--; fprintf(stderr, "included from %s at line %d:\n", err_file->file_name, err_file->lineno); + if (err_file == file_stack) + break; } } @@ -1368,6 +1386,7 @@ void die(const char *fmt, ...) DBUG_ENTER("die"); DBUG_PRINT("enter", ("start_lineno: %d", start_lineno)); + fflush(stdout); /* Print the error message */ fprintf(stderr, "mysqltest: "); if (cur_file && cur_file != file_stack) @@ -1406,7 +1425,7 @@ void die(const char *fmt, ...) been produced prior to the error */ if (cur_con && !cur_con->pending) - show_warnings_before_error(&cur_con->mysql); + show_warnings_before_error(cur_con->mysql); cleanup_and_exit(1); } @@ -1450,9 +1469,12 @@ void verbose_msg(const char *fmt, ...) { va_list args; DBUG_ENTER("verbose_msg"); + DBUG_PRINT("enter", ("format: %s", fmt)); + if (!verbose) DBUG_VOID_RETURN; + fflush(stdout); va_start(args, fmt); fprintf(stderr, "mysqltest: "); if (cur_file && cur_file != file_stack) @@ -1463,6 +1485,7 @@ void verbose_msg(const char *fmt, ...) vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); va_end(args); + fflush(stderr); DBUG_VOID_RETURN; } @@ -1547,6 +1570,8 @@ static int run_command(char* cmd, char buf[512]= {0}; FILE *res_file; int error; + DBUG_ENTER("run_command"); + DBUG_PRINT("enter", ("cmd: %s", cmd)); if (!(res_file= popen(cmd, "r"))) die("popen(\"%s\", \"r\") failed", cmd); @@ -1567,7 +1592,7 @@ static int run_command(char* cmd, } error= pclose(res_file); - return WEXITSTATUS(error); + DBUG_RETURN(WEXITSTATUS(error)); } @@ -2351,7 +2376,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end) *query_end : query + strlen(query)); MYSQL_RES *res; MYSQL_ROW row; - MYSQL* mysql = &cur_con->mysql; + MYSQL* mysql = cur_con->mysql; DYNAMIC_STRING ds_query; DBUG_ENTER("var_query_set"); LINT_INIT(res); @@ -2493,7 +2518,7 @@ void var_set_query_get_value(struct st_command *command, VAR *var) long row_no; int col_no= -1; MYSQL_RES* res; - MYSQL* mysql= &cur_con->mysql; + MYSQL* mysql= cur_con->mysql; static DYNAMIC_STRING ds_query; static DYNAMIC_STRING ds_col; @@ -3206,6 +3231,7 @@ void do_remove_files_wildcard(struct st_command *command) { int error= 0, sys_errno= 0; uint i; + size_t directory_length; MY_DIR *dir_info; FILEINFO *file; char dir_separator[2]; @@ -3236,8 +3262,8 @@ void do_remove_files_wildcard(struct st_command *command) } init_dynamic_string(&ds_file_to_remove, dirname, 1024, 1024); dir_separator[0]= FN_LIBCHAR; - dir_separator[1]= 0; - dynstr_append(&ds_file_to_remove, dir_separator); + dynstr_append_mem(&ds_file_to_remove, dir_separator, 1); + directory_length= ds_file_to_remove.length; /* Set default wild chars for wild_compare, is changed in embedded mode */ set_wild_chars(1); @@ -3253,8 +3279,7 @@ void do_remove_files_wildcard(struct st_command *command) if (ds_wild.length && wild_compare(file->name, ds_wild.str, 0)) continue; - ds_file_to_remove.length= ds_directory.length + 1; - ds_file_to_remove.str[ds_directory.length + 1]= 0; + ds_file_to_remove.length= directory_length; dynstr_append(&ds_file_to_remove, file->name); DBUG_PRINT("info", ("removing file: %s", ds_file_to_remove.str)); if ((error= (my_delete(ds_file_to_remove.str, MYF(MY_WME)) != 0))) @@ -3932,7 +3957,7 @@ void do_send_quit(struct st_command *command) if (!(con= find_connection_by_name(name))) die("connection '%s' not found in connection pool", name); - simple_command(&con->mysql,COM_QUIT,0,0,1); + simple_command(con->mysql,COM_QUIT,0,0,1); DBUG_VOID_RETURN; } @@ -3956,7 +3981,8 @@ void do_send_quit(struct st_command *command) void do_change_user(struct st_command *command) { - MYSQL *mysql = &cur_con->mysql; + MYSQL *mysql = cur_con->mysql; + /* static keyword to make the NetWare compiler happy. */ static DYNAMIC_STRING ds_user, ds_passwd, ds_db; const struct command_arg change_user_args[] = { { "user", ARG_STRING, FALSE, &ds_user, "User to connect as" }, @@ -4152,7 +4178,7 @@ int do_echo(struct st_command *command) void do_wait_for_slave_to_stop(struct st_command *c __attribute__((unused))) { static int SLAVE_POLL_INTERVAL= 300000; - MYSQL* mysql = &cur_con->mysql; + MYSQL* mysql = cur_con->mysql; for (;;) { MYSQL_RES *UNINIT_VAR(res); @@ -4182,7 +4208,7 @@ void do_sync_with_master2(struct st_command *command, long offset) { MYSQL_RES *res; MYSQL_ROW row; - MYSQL *mysql= &cur_con->mysql; + MYSQL *mysql= cur_con->mysql; char query_buf[FN_REFLEN+128]; int timeout= 300; /* seconds */ @@ -4272,7 +4298,7 @@ int do_save_master_pos() { MYSQL_RES *res; MYSQL_ROW row; - MYSQL *mysql = &cur_con->mysql; + MYSQL *mysql = cur_con->mysql; const char *query; DBUG_ENTER("do_save_master_pos"); @@ -4659,7 +4685,7 @@ void do_shutdown_server(struct st_command *command) long timeout=60; int pid; DYNAMIC_STRING ds_pidfile_name; - MYSQL* mysql = &cur_con->mysql; + MYSQL* mysql = cur_con->mysql; static DYNAMIC_STRING ds_timeout; const struct command_arg shutdown_args[] = { {"timeout", ARG_STRING, FALSE, &ds_timeout, "Timeout before killing server"} @@ -5002,7 +5028,7 @@ void set_current_connection(struct st_connection *con) cur_con= con; /* Update $mysql_get_server_version to that of current connection */ var_set_int("$mysql_get_server_version", - mysql_get_server_version(&con->mysql)); + mysql_get_server_version(con->mysql)); /* Update $CURRENT_CONNECTION to the name of the current connection */ var_set_string("$CURRENT_CONNECTION", con->name); } @@ -5075,10 +5101,10 @@ void do_close_connection(struct st_command *command) #ifndef EMBEDDED_LIBRARY if (command->type == Q_DIRTY_CLOSE) { - if (con->mysql.net.vio) + if (con->mysql->net.vio) { - vio_delete(con->mysql.net.vio); - con->mysql.net.vio = 0; + vio_delete(con->mysql->net.vio); + con->mysql->net.vio = 0; } } #else @@ -5093,7 +5119,8 @@ void do_close_connection(struct st_command *command) mysql_stmt_close(con->stmt); con->stmt= 0; - mysql_close(&con->mysql); + mysql_close(con->mysql); + con->mysql= 0; if (con->util_mysql) mysql_close(con->util_mysql); @@ -5456,28 +5483,29 @@ void do_connect(struct st_command *command) if (!(con_slot= find_connection_by_name("-closed_connection-"))) die("Connection limit exhausted, you can have max %d connections", opt_max_connections); + my_free(con_slot->name); + con_slot->name= 0; } #ifdef EMBEDDED_LIBRARY init_connection_thd(con_slot); #endif /*EMBEDDED_LIBRARY*/ - if (!mysql_init(&con_slot->mysql)) + if (!(con_slot->mysql= mysql_init(0))) die("Failed on mysql_init()"); if (opt_connect_timeout) - mysql_options(&con_slot->mysql, MYSQL_OPT_CONNECT_TIMEOUT, + mysql_options(con_slot->mysql, MYSQL_OPT_CONNECT_TIMEOUT, (void *) &opt_connect_timeout); if (opt_compress || con_compress) - mysql_options(&con_slot->mysql, MYSQL_OPT_COMPRESS, NullS); - mysql_options(&con_slot->mysql, MYSQL_OPT_LOCAL_INFILE, 0); - mysql_options(&con_slot->mysql, MYSQL_SET_CHARSET_NAME, + mysql_options(con_slot->mysql, MYSQL_OPT_COMPRESS, NullS); + mysql_options(con_slot->mysql, MYSQL_OPT_LOCAL_INFILE, 0); + mysql_options(con_slot->mysql, MYSQL_SET_CHARSET_NAME, charset_info->csname); if (opt_charsets_dir) - mysql_options(&con_slot->mysql, MYSQL_SET_CHARSET_DIR, + mysql_options(con_slot->mysql, MYSQL_SET_CHARSET_DIR, opt_charsets_dir); - #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) if (opt_use_ssl) con_ssl= 1; @@ -5486,12 +5514,12 @@ void do_connect(struct st_command *command) if (con_ssl) { #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) - mysql_ssl_set(&con_slot->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, + mysql_ssl_set(con_slot->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); #if MYSQL_VERSION_ID >= 50000 /* Turn on ssl_verify_server_cert only if host is "localhost" */ opt_ssl_verify_server_cert= !strcmp(ds_host.str, "localhost"); - mysql_options(&con_slot->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, + mysql_options(con_slot->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &opt_ssl_verify_server_cert); #endif #endif @@ -5505,7 +5533,7 @@ void do_connect(struct st_command *command) } if (opt_protocol) - mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol); + mysql_options(con_slot->mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol); #ifdef HAVE_SMEM if (con_shm) @@ -5513,12 +5541,12 @@ void do_connect(struct st_command *command) uint protocol= MYSQL_PROTOCOL_MEMORY; if (!ds_shm.length) die("Missing shared memory base name"); - mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, ds_shm.str); - mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol); + mysql_options(con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, ds_shm.str); + mysql_options(con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol); } else if (shared_memory_base_name) { - mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, + mysql_options(con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, shared_memory_base_name); } #endif @@ -5528,16 +5556,16 @@ void do_connect(struct st_command *command) dynstr_set(&ds_database, opt_db); if (opt_plugin_dir && *opt_plugin_dir) - mysql_options(&con_slot->mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir); + mysql_options(con_slot->mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir); if (ds_default_auth.length) - mysql_options(&con_slot->mysql, MYSQL_DEFAULT_AUTH, ds_default_auth.str); + mysql_options(con_slot->mysql, MYSQL_DEFAULT_AUTH, ds_default_auth.str); /* 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, &con_slot->mysql, + if (connect_n_handle_errors(command, con_slot->mysql, ds_host.str,ds_user.str, ds_password.str, ds_database.str, con_port, ds_sock.str)) @@ -6403,7 +6431,7 @@ static struct my_option my_long_options[] = {"max-connections", OPT_MAX_CONNECTIONS, "Max number of open connections to server", &opt_max_connections, &opt_max_connections, 0, - GET_INT, REQUIRED_ARG, 128, 8, 5120, 0, 0, 0}, + GET_INT, REQUIRED_ARG, DEFAULT_MAX_CONN, 8, 5120, 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}, {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).", @@ -6553,6 +6581,7 @@ get_one_option(int optid, const struct my_option *opt, char *argument) #ifndef DBUG_OFF DBUG_PUSH(argument ? argument : "d:t:S:i:O,/tmp/mysqltest.trace"); debug_check_flag= 1; + debug_info_flag= 1; #endif break; case 'r': @@ -6668,7 +6697,7 @@ int parse_args(int argc, char **argv) if (debug_info_flag) my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; if (debug_check_flag) - my_end_arg= MY_CHECK_ERROR; + my_end_arg|= MY_CHECK_ERROR; if (global_subst != NULL) { @@ -6973,6 +7002,7 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, my_bool *is_null; ulong *length; uint i; + int error; /* Allocate array with bind structs, lengths and NULL flags */ my_bind= (MYSQL_BIND*) my_malloc(num_fields * sizeof(MYSQL_BIND), @@ -7000,7 +7030,7 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, die("mysql_stmt_bind_result failed: %d: %s", mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); - while (mysql_stmt_fetch(stmt) == 0) + while ((error=mysql_stmt_fetch(stmt)) == 0) { for (i= 0; i < num_fields; i++) append_field(ds, i, &fields[i], (char*)my_bind[i].buffer, @@ -7009,8 +7039,11 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, dynstr_append_mem(ds, "\n", 1); } + if (error != MYSQL_NO_DATA) + die("mysql_fetch didn't end with MYSQL_NO_DATA from statement: error: %d", + error); if (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA) - die("fetch didn't end with MYSQL_NO_DATA from statement: %d %s", + die("mysql_fetch didn't end with MYSQL_NO_DATA from statement: %d %s", mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); for (i= 0; i < num_fields; i++) @@ -7105,6 +7138,8 @@ void append_table_headings(DYNAMIC_STRING *ds, uint num_fields) { uint col_idx; + if (disable_column_names) + return; for (col_idx= 0; col_idx < num_fields; col_idx++) { if (col_idx) @@ -7171,12 +7206,22 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings) { MYSQL_RES *res= 0; - MYSQL *mysql= &cn->mysql; + MYSQL *mysql= cn->mysql; int err= 0, counter= 0; DBUG_ENTER("run_query_normal"); DBUG_PRINT("enter",("flags: %d", flags)); DBUG_PRINT("enter", ("query: '%-.60s'", query)); + if (!mysql) + { + /* Emulate old behaviour of sending something on a closed connection */ + handle_error(command, 2006, "MySQL server has gone away", + "000000", ds); + cn->pending= FALSE; + var_set_errno(2006); + DBUG_VOID_RETURN; + } + if (flags & QUERY_SEND_FLAG) { /* @@ -7363,7 +7408,7 @@ void handle_error(struct st_command *command, DBUG_ENTER("handle_error"); - if (command->require_file[0]) + if (command->require_file) { /* The query after a "--require" failed. This is fine as long the server @@ -7726,7 +7771,8 @@ int util_query(MYSQL* org_mysql, const char* query){ cur_con->util_mysql= mysql; } - DBUG_RETURN(mysql_query(mysql, query)); + int ret= mysql_query(mysql, query); + DBUG_RETURN(ret); } @@ -7746,7 +7792,7 @@ int util_query(MYSQL* org_mysql, const char* query){ void run_query(struct st_connection *cn, struct st_command *command, int flags) { - MYSQL *mysql= &cn->mysql; + MYSQL *mysql= cn->mysql; DYNAMIC_STRING *ds; DYNAMIC_STRING *save_ds= NULL; DYNAMIC_STRING ds_result; @@ -7791,7 +7837,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) Create a temporary dynamic string to contain the output from this query. */ - if (command->require_file[0]) + if (command->require_file) { init_dynamic_string(&ds_result, "", 1024, 1024); ds= &ds_result; @@ -7809,6 +7855,15 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) dynstr_append_mem(ds, "\n", 1); } + /* + Write the command to the result file before we execute the query + This is needed to be able to analyse the log if something goes + wrong + */ + log_file.write(&ds_res); + log_file.flush(); + dynstr_set(&ds_res, 0); + if (view_protocol_enabled && complete_query && match_re(&view_re, query)) @@ -7950,7 +8005,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) mysql_errno(mysql), mysql_error(mysql)); } - if (command->require_file[0]) + if (command->require_file) { /* A result file was specified for _this_ query and the output should be checked against an already @@ -8295,6 +8350,7 @@ int main(int argc, char **argv) char save_file[FN_REFLEN]; bool empty_result= FALSE; MY_INIT(argv[0]); + DBUG_ENTER("main"); save_file[0]= 0; TMPDIR[0]= 0; @@ -8326,8 +8382,8 @@ int main(int argc, char **argv) my_init_dynamic_array(&q_lines, sizeof(struct st_command*), 1024, 1024); - if (my_hash_init(&var_hash, charset_info, - 1024, 0, 0, get_var_key, var_free, MYF(0))) + if (my_hash_init2(&var_hash, 64, charset_info, + 128, 0, 0, get_var_key, var_free, MYF(0))) die("Variable hash initialization failed"); var_set_string("MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION); @@ -8354,6 +8410,7 @@ int main(int argc, char **argv) #endif init_dynamic_string(&ds_res, "", 2048, 2048); + init_alloc_root(&require_file_root, 1024, 1024); parse_args(argc, argv); @@ -8416,33 +8473,33 @@ int main(int argc, char **argv) #ifdef EMBEDDED_LIBRARY init_connection_thd(con); #endif /*EMBEDDED_LIBRARY*/ - if (!( mysql_init(&con->mysql))) + if (! (con->mysql= mysql_init(0))) die("Failed in mysql_init()"); if (opt_connect_timeout) - mysql_options(&con->mysql, MYSQL_OPT_CONNECT_TIMEOUT, + mysql_options(con->mysql, MYSQL_OPT_CONNECT_TIMEOUT, (void *) &opt_connect_timeout); if (opt_compress) - mysql_options(&con->mysql,MYSQL_OPT_COMPRESS,NullS); - mysql_options(&con->mysql, MYSQL_OPT_LOCAL_INFILE, 0); - mysql_options(&con->mysql, MYSQL_SET_CHARSET_NAME, + mysql_options(con->mysql,MYSQL_OPT_COMPRESS,NullS); + mysql_options(con->mysql, MYSQL_OPT_LOCAL_INFILE, 0); + mysql_options(con->mysql, MYSQL_SET_CHARSET_NAME, charset_info->csname); if (opt_charsets_dir) - mysql_options(&con->mysql, MYSQL_SET_CHARSET_DIR, + mysql_options(con->mysql, MYSQL_SET_CHARSET_DIR, opt_charsets_dir); if (opt_protocol) - mysql_options(&con->mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); + mysql_options(con->mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) if (opt_use_ssl) { - mysql_ssl_set(&con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, + mysql_ssl_set(con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); #if MYSQL_VERSION_ID >= 50000 /* Turn on ssl_verify_server_cert only if host is "localhost" */ opt_ssl_verify_server_cert= opt_host && !strcmp(opt_host, "localhost"); - mysql_options(&con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, + mysql_options(con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &opt_ssl_verify_server_cert); #endif } @@ -8450,13 +8507,13 @@ int main(int argc, char **argv) #ifdef HAVE_SMEM if (shared_memory_base_name) - mysql_options(&con->mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); + mysql_options(con->mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); #endif if (!(con->name = my_strdup("default", MYF(MY_WME)))) die("Out of memory"); - safe_connect(&con->mysql, con->name, opt_host, opt_user, opt_pass, + safe_connect(con->mysql, con->name, opt_host, opt_user, opt_pass, opt_db, opt_port, unix_sock); /* Use all time until exit if no explicit 'start_timer' */ @@ -8592,6 +8649,14 @@ int main(int argc, char **argv) display_metadata= 0; var_set_int("$ENABLED_METADATA", 0); break; + case Q_ENABLE_COLUMN_NAMES: + disable_column_names= 0; + var_set_int("$ENABLED_COLUMN_NAMES", 0); + break; + case Q_DISABLE_COLUMN_NAMES: + disable_column_names= 1; + var_set_int("$ENABLED_COLUMN_NAMES", 1); + break; case Q_SOURCE: do_source(command); break; case Q_SLEEP: do_sleep(command, 0); break; case Q_REAL_SLEEP: do_sleep(command, 1); break; @@ -8682,7 +8747,9 @@ int main(int argc, char **argv) if (save_file[0]) { - strmake(command->require_file, save_file, sizeof(save_file) - 1); + if (!(command->require_file= strdup_root(&require_file_root, + save_file))) + die("out of memory for require_file"); save_file[0]= 0; } run_query(cur_con, command, flags); @@ -8780,11 +8847,11 @@ int main(int argc, char **argv) dynstr_append(&ds_res, "\n"); break; case Q_PING: - handle_command_error(command, mysql_ping(&cur_con->mysql), -1); + handle_command_error(command, mysql_ping(cur_con->mysql), -1); break; case Q_SEND_SHUTDOWN: handle_command_error(command, - mysql_shutdown(&cur_con->mysql, + mysql_shutdown(cur_con->mysql, SHUTDOWN_DEFAULT), -1); break; case Q_SHUTDOWN_SERVER: @@ -8814,10 +8881,10 @@ int main(int argc, char **argv) ps_protocol_enabled= ps_protocol; break; case Q_DISABLE_RECONNECT: - set_reconnect(&cur_con->mysql, 0); + set_reconnect(cur_con->mysql, 0); break; case Q_ENABLE_RECONNECT: - set_reconnect(&cur_con->mysql, 1); + set_reconnect(cur_con->mysql, 1); /* Close any open statements - no reconnect, need new prepare */ close_statements(); break; @@ -9007,7 +9074,7 @@ void timer_output(void) ulonglong timer_now(void) { - return my_micro_time() / 1000; + return my_interval_timer() / 1000000; } diff --git a/client/readline.cc b/client/readline.cc index f6d3d1295f1..51cbd89f29f 100644 --- a/client/readline.cc +++ b/client/readline.cc @@ -31,9 +31,9 @@ static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length); LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file) { LINE_BUFFER *line_buff; - MY_STAT input_file_stat; #ifndef __WIN__ + MY_STAT input_file_stat; if (my_fstat(fileno(file), &input_file_stat, MYF(MY_WME)) || MY_S_ISDIR(input_file_stat.st_mode) || MY_S_ISBLK(input_file_stat.st_mode)) @@ -56,6 +56,7 @@ char *batch_readline(LINE_BUFFER *line_buff) { char *pos; ulong out_length; + LINT_INIT(out_length); if (!(pos=intern_read_line(line_buff, &out_length))) return 0; diff --git a/client/sql_string.cc b/client/sql_string.cc index dec6ac94eb2..684e9f337af 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -481,11 +481,11 @@ uint32 String::numchars() return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length); } -int String::charpos(int i,uint32 offset) +int String::charpos(longlong i,uint32 offset) { if (i <= 0) - return i; - return str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,i); + return (int)i; + return (int)str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,(size_t)i); } int String::strstr(const String &s,uint32 offset) diff --git a/client/sql_string.h b/client/sql_string.h index f406da28995..bc0179d1e45 100644 --- a/client/sql_string.h +++ b/client/sql_string.h @@ -1,5 +1,5 @@ -#ifndef CLIENT_SQL_STRING_INCLUDED -#define CLIENT_SQL_STRING_INCLUDED +#ifndef SQL_STRING_INCLUDED +#define SQL_STRING_INCLUDED /* Copyright (C) 2000 MySQL AB @@ -268,7 +268,7 @@ public: friend int stringcmp(const String *a,const String *b); friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); uint32 numchars(); - int charpos(int i,uint32 offset=0); + int charpos(longlong i,uint32 offset=0); int reserve(uint32 space_needed) { @@ -357,4 +357,4 @@ public: } }; -#endif /* CLIENT_SQL_STRING_INCLUDED */ +#endif /* SQL_STRING_INCLUDED */ |