diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 4b336d246c6..ed2613eaef0 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -259,8 +259,7 @@ enum enum_commands { Q_SEND, Q_REAP, Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN, Q_PING, Q_EVAL, - Q_RPL_PROBE, Q_ENABLE_RPL_PARSE, - Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT, + Q_EVAL_RESULT, Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG, Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG, Q_WAIT_FOR_SLAVE_TO_STOP, @@ -319,9 +318,6 @@ const char *command_names[]= "replace_column", "ping", "eval", - "rpl_probe", - "enable_rpl_parse", - "disable_rpl_parse", "eval_result", /* Enable/disable that the _query_ is logged to result file */ "enable_query_log", @@ -661,14 +657,6 @@ public: LogFile log_file; LogFile progress_file; - -/* Disable functions that only exist in MySQL 4.0 */ -#if MYSQL_VERSION_ID < 40000 -void mysql_enable_rpl_parse(MYSQL* mysql __attribute__((unused))) {} -void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {} -int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; } -my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; } -#endif void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, int len); void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val); @@ -3850,12 +3838,8 @@ int do_save_master_pos() MYSQL_ROW row; MYSQL *mysql = &cur_con->mysql; const char *query; - int rpl_parse; DBUG_ENTER("do_save_master_pos"); - rpl_parse = mysql_rpl_parse_enabled(mysql); - mysql_disable_rpl_parse(mysql); - #ifdef HAVE_NDB_BINLOG /* Wait for ndb binlog to be up-to-date with all changes @@ -4005,10 +3989,6 @@ int do_save_master_pos() strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1); master_pos.pos = strtoul(row[1], (char**) 0, 10); mysql_free_result(res); - - if (rpl_parse) - mysql_enable_rpl_parse(mysql); - DBUG_RETURN(0); } @@ -4071,29 +4051,6 @@ void do_let(struct st_command *command) } -int do_rpl_probe(struct st_command *command __attribute__((unused))) -{ - DBUG_ENTER("do_rpl_probe"); - if (mysql_rpl_probe(&cur_con->mysql)) - die("Failed in mysql_rpl_probe(): '%s'", mysql_error(&cur_con->mysql)); - DBUG_RETURN(0); -} - - -int do_enable_rpl_parse(struct st_command *command __attribute__((unused))) -{ - mysql_enable_rpl_parse(&cur_con->mysql); - return 0; -} - - -int do_disable_rpl_parse(struct st_command *command __attribute__((unused))) -{ - mysql_disable_rpl_parse(&cur_con->mysql); - return 0; -} - - /* Sleep the number of specified seconds @@ -6512,8 +6469,6 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, if (!disable_result_log) { - ulonglong UNINIT_VAR(affected_rows); /* Ok to be undef if 'disable_info' is set */ - if (res) { MYSQL_FIELD *fields= mysql_fetch_fields(res); @@ -6530,10 +6485,10 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, /* Need to call mysql_affected_rows() before the "new" - query to find the warnings + query to find the warnings. */ if (!disable_info) - affected_rows= mysql_affected_rows(mysql); + append_info(ds, mysql_affected_rows(mysql), mysql_info(mysql)); /* Add all warnings to the result. We can't do this if we are in @@ -6548,9 +6503,6 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, dynstr_append_mem(ds, ds_warnings->str, ds_warnings->length); } } - - if (!disable_info) - append_info(ds, affected_rows, mysql_info(mysql)); } if (res) @@ -6923,6 +6875,13 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command, */ } + /* + Fetch info before fetching warnings, since it will be reset + otherwise. + */ + if (!disable_info) + append_info(ds, mysql_stmt_affected_rows(stmt), mysql_info(mysql)); + if (!disable_warnings) { /* Get the warnings from execute */ @@ -6946,9 +6905,6 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command, } } - if (!disable_info) - append_info(ds, mysql_affected_rows(mysql), mysql_info(mysql)); - } end: @@ -7761,9 +7717,6 @@ int main(int argc, char **argv) case Q_DISCONNECT: case Q_DIRTY_CLOSE: do_close_connection(command); break; - case Q_RPL_PROBE: do_rpl_probe(command); break; - case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(command); break; - case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(command); break; case Q_ENABLE_QUERY_LOG: disable_query_log=0; break; case Q_DISABLE_QUERY_LOG: disable_query_log=1; break; case Q_ENABLE_ABORT_ON_ERROR: abort_on_error=1; break; diff --git a/include/mysql.h b/include/mysql.h index 70faf3cb2c1..ca682e6f30b 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -188,24 +188,10 @@ struct st_mysql_options { unsigned long max_allowed_packet; my_bool use_ssl; /* if to use SSL or not */ my_bool compress,named_pipe; - /* - On connect, find out the replication role of the server, and - establish connections to all the peers - */ - my_bool rpl_probe; - /* - Each call to mysql_real_query() will parse it to tell if it is a read - or a write, and direct it to the slave or the master - */ - my_bool rpl_parse; - /* - If set, never read from a master, only from slave, when doing - a read that is replication-aware - */ - my_bool no_master_reads; -#if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY) - my_bool separate_thread; -#endif + my_bool unused1; + my_bool unused2; + my_bool unused3; + my_bool unused4; enum mysql_option methods_to_use; char *client_ip; /* Refuse client connecting to server if it uses old (pre-4.1.1) protocol */ @@ -232,15 +218,6 @@ enum mysql_protocol_type MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET, MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY }; -/* - There are three types of queries - the ones that have to go to - the master, the ones that go to a slave, and the adminstrative - type which must happen on the pivot connectioin -*/ -enum mysql_rpl_type -{ - MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN -}; typedef struct character_set { @@ -285,21 +262,8 @@ typedef struct st_mysql /* session-wide random string */ char scramble[SCRAMBLE_LENGTH+1]; - - /* - Set if this is the original connection, not a master or a slave we have - added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave() - */ - my_bool rpl_pivot; - /* - Pointers to the master, and the next slave connections, points to - itself if lone connection. - */ - struct st_mysql* master, *next_slave; - - struct st_mysql* last_used_slave; /* needed for round-robin slave pick */ - /* needed for send/read/store/use result to work correctly with replication */ - struct st_mysql* last_used_con; + my_bool unused1; + void *unused2, *unused3, *unused4, *unused5; LIST *stmts; /* list of all statements */ const struct st_mysql_methods *methods; @@ -333,35 +297,12 @@ typedef struct st_mysql_res { void *extension; } MYSQL_RES; -#define MAX_MYSQL_MANAGER_ERR 256 -#define MAX_MYSQL_MANAGER_MSG 256 - -#define MANAGER_OK 200 -#define MANAGER_INFO 250 -#define MANAGER_ACCESS 401 -#define MANAGER_CLIENT_ERR 450 -#define MANAGER_INTERNAL_ERR 500 #if !defined(MYSQL_SERVER) && !defined(MYSQL_CLIENT) #define MYSQL_CLIENT #endif -typedef struct st_mysql_manager -{ - NET net; - char *host, *user, *passwd; - char *net_buf, *net_buf_pos, *net_data_end; - unsigned int port; - int cmd_status; - int last_errno; - int net_buf_size; - my_bool free_me; - my_bool eof; - char last_error[MAX_MYSQL_MANAGER_ERR]; - void *extension; -} MYSQL_MANAGER; - typedef struct st_mysql_parameters { unsigned long *p_max_allowed_packet; @@ -454,16 +395,6 @@ int STDCALL mysql_real_query(MYSQL *mysql, const char *q, MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql); MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql); -/* perform query on master */ -my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q, - unsigned long length); -my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q, - unsigned long length); -/* perform query on slave */ -my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q, - unsigned long length); -my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q, - unsigned long length); void STDCALL mysql_get_character_set_info(MYSQL *mysql, MY_CHARSET_INFO *charset); @@ -485,37 +416,6 @@ mysql_set_local_infile_handler(MYSQL *mysql, void mysql_set_local_infile_default(MYSQL *mysql); - -/* - enable/disable parsing of all queries to decide if they go on master or - slave -*/ -void STDCALL mysql_enable_rpl_parse(MYSQL* mysql); -void STDCALL mysql_disable_rpl_parse(MYSQL* mysql); -/* get the value of the parse flag */ -int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql); - -/* enable/disable reads from master */ -void STDCALL mysql_enable_reads_from_master(MYSQL* mysql); -void STDCALL mysql_disable_reads_from_master(MYSQL* mysql); -/* get the value of the master read flag */ -my_bool STDCALL mysql_reads_from_master_enabled(MYSQL* mysql); - -enum mysql_rpl_type STDCALL mysql_rpl_query_type(const char* q, int len); - -/* discover the master and its slaves */ -my_bool STDCALL mysql_rpl_probe(MYSQL* mysql); - -/* set the master, close/free the old one, if it is not a pivot */ -int STDCALL mysql_set_master(MYSQL* mysql, const char* host, - unsigned int port, - const char* user, - const char* passwd); -int STDCALL mysql_add_slave(MYSQL* mysql, const char* host, - unsigned int port, - const char* user, - const char* passwd); - int STDCALL mysql_shutdown(MYSQL *mysql, enum mysql_enum_shutdown_level shutdown_level); @@ -562,18 +462,6 @@ void STDCALL mysql_debug(const char *debug); void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name); unsigned int STDCALL mysql_thread_safe(void); my_bool STDCALL mysql_embedded(void); -MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con); -MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con, - const char* host, - const char* user, - const char* passwd, - unsigned int port); -void STDCALL mysql_manager_close(MYSQL_MANAGER* con); -int STDCALL mysql_manager_command(MYSQL_MANAGER* con, - const char* cmd, int cmd_len); -int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, - char* res_buf, - int res_buf_size); my_bool STDCALL mysql_read_query_result(MYSQL *mysql); @@ -842,7 +730,6 @@ MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd); int STDCALL mysql_create_db(MYSQL *mysql, const char *DB); int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB); -#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT) #endif #define HAVE_MYSQL_REAL_CONNECT diff --git a/include/mysql.h.pp b/include/mysql.h.pp index 3d1304bf460..0b809a6ab23 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -277,10 +277,10 @@ struct st_mysql_options { unsigned long max_allowed_packet; my_bool use_ssl; my_bool compress,named_pipe; - my_bool rpl_probe; - my_bool rpl_parse; - my_bool no_master_reads; - my_bool separate_thread; + my_bool unused1; + my_bool unused2; + my_bool unused3; + my_bool unused4; enum mysql_option methods_to_use; char *client_ip; my_bool secure_auth; @@ -301,10 +301,6 @@ enum mysql_protocol_type MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET, MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY }; -enum mysql_rpl_type -{ - MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN -}; typedef struct character_set { unsigned int number; @@ -344,10 +340,8 @@ typedef struct st_mysql my_bool free_me; my_bool reconnect; char scramble[20 +1]; - my_bool rpl_pivot; - struct st_mysql* master, *next_slave; - struct st_mysql* last_used_slave; - struct st_mysql* last_used_con; + my_bool unused1; + void *unused2, *unused3, *unused4, *unused5; LIST *stmts; const struct st_mysql_methods *methods; void *thd; @@ -371,20 +365,6 @@ typedef struct st_mysql_res { my_bool unbuffered_fetch_cancelled; void *extension; } MYSQL_RES; -typedef struct st_mysql_manager -{ - NET net; - char *host, *user, *passwd; - char *net_buf, *net_buf_pos, *net_data_end; - unsigned int port; - int cmd_status; - int last_errno; - int net_buf_size; - my_bool free_me; - my_bool eof; - char last_error[256]; - void *extension; -} MYSQL_MANAGER; typedef struct st_mysql_parameters { unsigned long *p_max_allowed_packet; @@ -437,14 +417,6 @@ int mysql_real_query(MYSQL *mysql, const char *q, unsigned long length); MYSQL_RES * mysql_store_result(MYSQL *mysql); MYSQL_RES * mysql_use_result(MYSQL *mysql); -my_bool mysql_master_query(MYSQL *mysql, const char *q, - unsigned long length); -my_bool mysql_master_send_query(MYSQL *mysql, const char *q, - unsigned long length); -my_bool mysql_slave_query(MYSQL *mysql, const char *q, - unsigned long length); -my_bool mysql_slave_send_query(MYSQL *mysql, const char *q, - unsigned long length); void mysql_get_character_set_info(MYSQL *mysql, MY_CHARSET_INFO *charset); void @@ -459,22 +431,6 @@ mysql_set_local_infile_handler(MYSQL *mysql, void *); void mysql_set_local_infile_default(MYSQL *mysql); -void mysql_enable_rpl_parse(MYSQL* mysql); -void mysql_disable_rpl_parse(MYSQL* mysql); -int mysql_rpl_parse_enabled(MYSQL* mysql); -void mysql_enable_reads_from_master(MYSQL* mysql); -void mysql_disable_reads_from_master(MYSQL* mysql); -my_bool mysql_reads_from_master_enabled(MYSQL* mysql); -enum mysql_rpl_type mysql_rpl_query_type(const char* q, int len); -my_bool mysql_rpl_probe(MYSQL* mysql); -int mysql_set_master(MYSQL* mysql, const char* host, - unsigned int port, - const char* user, - const char* passwd); -int mysql_add_slave(MYSQL* mysql, const char* host, - unsigned int port, - const char* user, - const char* passwd); int mysql_shutdown(MYSQL *mysql, enum mysql_enum_shutdown_level shutdown_level); @@ -521,18 +477,6 @@ void mysql_debug(const char *debug); void myodbc_remove_escape(MYSQL *mysql,char *name); unsigned int mysql_thread_safe(void); my_bool mysql_embedded(void); -MYSQL_MANAGER* mysql_manager_init(MYSQL_MANAGER* con); -MYSQL_MANAGER* mysql_manager_connect(MYSQL_MANAGER* con, - const char* host, - const char* user, - const char* passwd, - unsigned int port); -void mysql_manager_close(MYSQL_MANAGER* con); -int mysql_manager_command(MYSQL_MANAGER* con, - const char* cmd, int cmd_len); -int mysql_manager_fetch_line(MYSQL_MANAGER* con, - char* res_buf, - int res_buf_size); my_bool mysql_read_query_result(MYSQL *mysql); enum enum_mysql_stmt_state { diff --git a/include/mysql_com.h b/include/mysql_com.h index 5e1b6b8504a..2641aeda205 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -408,10 +408,6 @@ void my_net_set_write_timeout(NET *net, uint timeout); void my_net_set_read_timeout(NET *net, uint timeout); #endif -/* - The following function is not meant for normal usage - Currently it's used internally by manager.c -*/ struct sockaddr; int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen, unsigned int timeout); diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index 805551b7ee3..84ad50e03e3 100755 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -73,7 +73,7 @@ SET(CLIENT_SOURCES ../mysys/array.c ../strings/bchange.c ../strings/bmove.c ../mysys/hash.c ../mysys/my_sleep.c ../mysys/default_modify.c get_password.c ../strings/int2str.c ../strings/is_prefix.c libmysql.c ../mysys/list.c ../strings/llstr.c - ../strings/longlong2str.c manager.c ../mysys/mf_arr_appstr.c ../mysys/mf_cache.c + ../strings/longlong2str.c ../mysys/mf_arr_appstr.c ../mysys/mf_cache.c ../mysys/mf_dirname.c ../mysys/mf_fn_ext.c ../mysys/mf_format.c ../mysys/mf_iocache.c ../mysys/mf_iocache2.c ../mysys/mf_loadpath.c ../mysys/mf_pack.c ../mysys/mf_path.c ../mysys/mf_tempfile.c ../mysys/mf_unixpath.c diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index eb4fd75ed11..acc709bfb89 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -31,7 +31,7 @@ pkglib_LTLIBRARIES = $(target) noinst_PROGRAMS = conf_to_src -target_sources = libmysql.c password.c manager.c \ +target_sources = libmysql.c password.c \ get_password.c errmsg.c mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \ diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 1264f2765ba..f922c98de3a 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -249,16 +249,6 @@ void STDCALL mysql_thread_end() #endif } -/* - Let the user specify that we don't want SIGPIPE; This doesn't however work - with threaded applications as we can have multiple read in progress. -*/ -static MYSQL* spawn_init(MYSQL* parent, const char* host, - unsigned int port, - const char* user, - const char* passwd); - - /* Expand wildcard to a sql string @@ -320,7 +310,7 @@ mysql_debug(const char *debug __attribute__((unused))) /************************************************************************** - Close the server connection if we get a SIGPIPE + Ignore SIGPIPE handler ARGSUSED **************************************************************************/ @@ -333,305 +323,6 @@ my_pipe_sig_handler(int sig __attribute__((unused))) #endif } -/* perform query on master */ -my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q, - unsigned long length) -{ - DBUG_ENTER("mysql_master_query"); - if (mysql_master_send_query(mysql, q, length)) - DBUG_RETURN(1); - DBUG_RETURN((*mysql->methods->read_query_result)(mysql)); -} - -my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q, - unsigned long length) -{ - MYSQL *master = mysql->master; - DBUG_ENTER("mysql_master_send_query"); - if (!master->net.vio && !mysql_real_connect(master,0,0,0,0,0,0,0)) - DBUG_RETURN(1); - master->reconnect= 1; - mysql->last_used_con = master; - DBUG_RETURN(simple_command(master, COM_QUERY, (const uchar*) q, length, 1)); -} - - -/* perform query on slave */ -my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q, - unsigned long length) -{ - DBUG_ENTER("mysql_slave_query"); - if (mysql_slave_send_query(mysql, q, length)) - DBUG_RETURN(1); - DBUG_RETURN((*mysql->methods->read_query_result)(mysql)); -} - - -my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q, - unsigned long length) -{ - MYSQL* last_used_slave, *slave_to_use = 0; - DBUG_ENTER("mysql_slave_send_query"); - - if ((last_used_slave = mysql->last_used_slave)) - slave_to_use = last_used_slave->next_slave; - else - slave_to_use = mysql->next_slave; - /* - Next_slave is always safe to use - we have a circular list of slaves - if there are no slaves, mysql->next_slave == mysql - */ - mysql->last_used_con = mysql->last_used_slave = slave_to_use; - if (!slave_to_use->net.vio && !mysql_real_connect(slave_to_use, 0,0,0, - 0,0,0,0)) - DBUG_RETURN(1); - slave_to_use->reconnect= 1; - DBUG_RETURN(simple_command(slave_to_use, COM_QUERY, (const uchar*) q, - length, 1)); -} - - -/* enable/disable parsing of all queries to decide - if they go on master or slave */ -void STDCALL mysql_enable_rpl_parse(MYSQL* mysql) -{ - mysql->options.rpl_parse = 1; -} - -void STDCALL mysql_disable_rpl_parse(MYSQL* mysql) -{ - mysql->options.rpl_parse = 0; -} - -/* get the value of the parse flag */ -int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql) -{ - return mysql->options.rpl_parse; -} - -/* enable/disable reads from master */ -void STDCALL mysql_enable_reads_from_master(MYSQL* mysql) -{ - mysql->options.no_master_reads = 0; -} - -void STDCALL mysql_disable_reads_from_master(MYSQL* mysql) -{ - mysql->options.no_master_reads = 1; -} - -/* get the value of the master read flag */ -my_bool STDCALL mysql_reads_from_master_enabled(MYSQL* mysql) -{ - return !(mysql->options.no_master_reads); -} - - -/* - We may get an error while doing replication internals. - In this case, we add a special explanation to the original - error -*/ - -static void expand_error(MYSQL* mysql, int error) -{ - char tmp[MYSQL_ERRMSG_SIZE]; - char *p; - uint err_length; - strmake(tmp, mysql->net.last_error, MYSQL_ERRMSG_SIZE-1); - p = strmake(mysql->net.last_error, ER(error), MYSQL_ERRMSG_SIZE-1); - err_length= (uint) (p - mysql->net.last_error); - strmake(p, tmp, MYSQL_ERRMSG_SIZE-1 - err_length); - mysql->net.last_errno = error; -} - -/* - This function assumes we have just called SHOW SLAVE STATUS and have - read the given result and row -*/ - -static my_bool get_master(MYSQL* mysql, MYSQL_RES* res, MYSQL_ROW row) -{ - MYSQL* master; - DBUG_ENTER("get_master"); - if (mysql_num_fields(res) < 3) - DBUG_RETURN(1); /* safety */ - - /* use the same username and password as the original connection */ - if (!(master = spawn_init(mysql, row[0], atoi(row[2]), 0, 0))) - DBUG_RETURN(1); - mysql->master = master; - DBUG_RETURN(0); -} - - -/* - Assuming we already know that mysql points to a master connection, - retrieve all the slaves -*/ - -static my_bool get_slaves_from_master(MYSQL* mysql) -{ - MYSQL_RES* res = 0; - MYSQL_ROW row; - my_bool error = 1; - int has_auth_info; - int port_ind; - DBUG_ENTER("get_slaves_from_master"); - - if (!mysql->net.vio && !mysql_real_connect(mysql,0,0,0,0,0,0,0)) - { - expand_error(mysql, CR_PROBE_MASTER_CONNECT); - DBUG_RETURN(1); - } - mysql->reconnect= 1; - - if (mysql_query(mysql, "SHOW SLAVE HOSTS") || - !(res = mysql_store_result(mysql))) - { - expand_error(mysql, CR_PROBE_SLAVE_HOSTS); - DBUG_RETURN(1); - } - - switch (mysql_num_fields(res)) { - case 5: - has_auth_info = 0; - port_ind=2; - break; - case 7: - has_auth_info = 1; - port_ind=4; - break; - default: - goto err; - } - - while ((row = mysql_fetch_row(res))) - { - MYSQL* slave; - const char* tmp_user, *tmp_pass; - - if (has_auth_info) - { - tmp_user = row[2]; - tmp_pass = row[3]; - } - else - { - tmp_user = mysql->user; - tmp_pass = mysql->passwd; - } - - if (!(slave = spawn_init(mysql, row[1], atoi(row[port_ind]), - tmp_user, tmp_pass))) - goto err; - - /* Now add slave into the circular linked list */ - slave->next_slave = mysql->next_slave; - mysql->next_slave = slave; - } - error = 0; -err: - if (res) - mysql_free_result(res); - DBUG_RETURN(error); -} - - -my_bool STDCALL mysql_rpl_probe(MYSQL* mysql) -{ - MYSQL_RES *res= 0; - MYSQL_ROW row; - my_bool error= 1; - DBUG_ENTER("mysql_rpl_probe"); - - /* - First determine the replication role of the server we connected to - the most reliable way to do this is to run SHOW SLAVE STATUS and see - if we have a non-empty master host. This is still not fool-proof - - it is not a sin to have a master that has a dormant slave thread with - a non-empty master host. However, it is more reliable to check - for empty master than whether the slave thread is actually running - */ - if (mysql_query(mysql, "SHOW SLAVE STATUS") || - !(res = mysql_store_result(mysql))) - { - expand_error(mysql, CR_PROBE_SLAVE_STATUS); - DBUG_RETURN(1); - } - - row= mysql_fetch_row(res); - /* - Check master host for emptiness/NULL - For MySQL 4.0 it's enough to check for row[0] - */ - if (row && row[0] && *(row[0])) - { - /* this is a slave, ask it for the master */ - if (get_master(mysql, res, row) || get_slaves_from_master(mysql)) - goto err; - } - else - { - mysql->master = mysql; - if (get_slaves_from_master(mysql)) - goto err; - } - - error = 0; -err: - if (res) - mysql_free_result(res); - DBUG_RETURN(error); -} - - -/* - Make a not so fool-proof decision on where the query should go, to - the master or the slave. Ideally the user should always make this - decision himself with mysql_master_query() or mysql_slave_query(). - However, to be able to more easily port the old code, we support the - option of an educated guess - this should work for most applications, - however, it may make the wrong decision in some particular cases. If - that happens, the user would have to change the code to call - mysql_master_query() or mysql_slave_query() explicitly in the place - where we have made the wrong decision -*/ - -enum mysql_rpl_type -STDCALL mysql_rpl_query_type(const char* q, int len) -{ - const char *q_end= q + len; - for (; q < q_end; ++q) - { - char c; - if (my_isalpha(&my_charset_latin1, (c= *q))) - { - switch (my_tolower(&my_charset_latin1,c)) { - case 'i': /* insert */ - case 'u': /* update or unlock tables */ - case 'l': /* lock tables or load data infile */ - case 'd': /* drop or delete */ - case 'a': /* alter */ - return MYSQL_RPL_MASTER; - case 'c': /* create or check */ - return my_tolower(&my_charset_latin1,q[1]) == 'h' ? MYSQL_RPL_ADMIN : - MYSQL_RPL_MASTER; - case 's': /* select or show */ - return my_tolower(&my_charset_latin1,q[1]) == 'h' ? MYSQL_RPL_ADMIN : - MYSQL_RPL_SLAVE; - case 'f': /* flush */ - case 'r': /* repair */ - case 'g': /* grant */ - return MYSQL_RPL_ADMIN; - default: - return MYSQL_RPL_SLAVE; - } - } - } - return MYSQL_RPL_MASTER; /* By default, send to master */ -} - /************************************************************************** Connect to sql server @@ -1093,68 +784,6 @@ mysql_query(MYSQL *mysql, const char *query) } -static MYSQL* spawn_init(MYSQL* parent, const char* host, - unsigned int port, const char* user, - const char* passwd) -{ - MYSQL* child; - DBUG_ENTER("spawn_init"); - if (!(child= mysql_init(0))) - DBUG_RETURN(0); - - child->options.user= my_strdup((user) ? user : - (parent->user ? parent->user : - parent->options.user), MYF(0)); - child->options.password= my_strdup((passwd) ? passwd : - (parent->passwd ? - parent->passwd : - parent->options.password), MYF(0)); - child->options.port= port; - child->options.host= my_strdup((host) ? host : - (parent->host ? - parent->host : - parent->options.host), MYF(0)); - if (parent->db) - child->options.db= my_strdup(parent->db, MYF(0)); - else if (parent->options.db) - child->options.db= my_strdup(parent->options.db, MYF(0)); - - /* - rpl_pivot is set to 1 in mysql_init(); Reset it as we are not doing - replication here - */ - child->rpl_pivot= 0; - DBUG_RETURN(child); -} - - -int -STDCALL mysql_set_master(MYSQL* mysql, const char* host, - unsigned int port, const char* user, - const char* passwd) -{ - if (mysql->master != mysql && !mysql->master->rpl_pivot) - mysql_close(mysql->master); - if (!(mysql->master = spawn_init(mysql, host, port, user, passwd))) - return 1; - return 0; -} - - -int -STDCALL mysql_add_slave(MYSQL* mysql, const char* host, - unsigned int port, - const char* user, - const char* passwd) -{ - MYSQL* slave; - if (!(slave = spawn_init(mysql, host, port, user, passwd))) - return 1; - slave->next_slave = mysql->next_slave; - mysql->next_slave = slave; - return 0; -} - /************************************************************************** Return next field of the query results **************************************************************************/ @@ -1483,17 +1112,17 @@ MYSQL_FIELD_OFFSET STDCALL mysql_field_tell(MYSQL_RES *res) unsigned int STDCALL mysql_field_count(MYSQL *mysql) { - return mysql->last_used_con->field_count; + return mysql->field_count; } my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql) { - return mysql->last_used_con->affected_rows; + return mysql->affected_rows; } my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql) { - return mysql->last_used_con->insert_id; + return mysql->insert_id; } const char *STDCALL mysql_sqlstate(MYSQL *mysql) @@ -1858,7 +1487,6 @@ my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) MYSQL_DATA *fields_data; DBUG_ENTER("cli_read_prepare_result"); - mysql= mysql->last_used_con; if ((packet_length= cli_safe_read(mysql)) == packet_error) DBUG_RETURN(1); mysql->warning_count= 0; @@ -2092,7 +1720,7 @@ static void alloc_stmt_fields(MYSQL_STMT *stmt) { MYSQL_FIELD *fields, *field, *end; MEM_ROOT *alloc= &stmt->mem_root; - MYSQL *mysql= stmt->mysql->last_used_con; + MYSQL *mysql= stmt->mysql; stmt->field_count= mysql->field_count; @@ -2479,7 +2107,6 @@ static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length) DBUG_ENTER("execute"); DBUG_DUMP("packet", (uchar *) packet, length); - mysql->last_used_con= mysql; int4store(buff, stmt->stmt_id); /* Send stmt id to server */ buff[4]= (char) stmt->flags; int4store(buff+5, 1); /* iteration count */ @@ -4689,7 +4316,6 @@ int cli_read_binary_rows(MYSQL_STMT *stmt) } net = &mysql->net; - mysql= mysql->last_used_con; while ((pkt_len= cli_safe_read(mysql)) != packet_error) { @@ -4787,8 +4413,6 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) DBUG_RETURN(1); } - mysql= mysql->last_used_con; - if (!stmt->field_count) DBUG_RETURN(0); @@ -5193,8 +4817,7 @@ my_bool STDCALL mysql_more_results(MYSQL *mysql) my_bool res; DBUG_ENTER("mysql_more_results"); - res= ((mysql->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS) ? - 1: 0); + res= ((mysql->server_status & SERVER_MORE_RESULTS_EXISTS) ? 1: 0); DBUG_PRINT("exit",("More results exists ? %d", res)); DBUG_RETURN(res); } @@ -5216,7 +4839,7 @@ int STDCALL mysql_next_result(MYSQL *mysql) net_clear_error(&mysql->net); mysql->affected_rows= ~(my_ulonglong) 0; - if (mysql->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS) + if (mysql->server_status & SERVER_MORE_RESULTS_EXISTS) DBUG_RETURN((*mysql->methods->next_result)(mysql)); DBUG_RETURN(-1); /* No more results */ diff --git a/libmysql/manager.c b/libmysql/manager.c deleted file mode 100644 index 53ffffa55c0..00000000000 --- a/libmysql/manager.c +++ /dev/null @@ -1,269 +0,0 @@ -/* Copyright (C) 2000-2004 MySQL 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 - the Free Software Foundation. - - There are special exceptions to the terms and conditions of the GPL as it - is applied to this software. View the full text of the exception in file - EXCEPTIONS-CLIENT in the directory of this software distribution. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include -#if defined(THREAD) -#include /* because of signal() */ -#endif -#include "mysql.h" -#include "mysql_version.h" -#include "mysqld_error.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__NETWARE__) -#include -#include -#include -#elif !defined( __WIN__) -#include -#ifdef HAVE_SYS_UN_H -# include -#endif -#include -#ifdef HAVE_SELECT_H -# include -#endif -#ifdef HAVE_SYS_SELECT_H -#include -#endif -#include -#endif /* __WIN__ */ - -#ifndef INADDR_NONE -#define INADDR_NONE -1 -#endif - -#define RES_BUF_SHIFT 5 -#define NET_BUF_SIZE 2048 - -MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con) -{ - int net_buf_size=NET_BUF_SIZE; - if (!con) - { - if (!(con=(MYSQL_MANAGER*)my_malloc(sizeof(*con)+net_buf_size, - MYF(MY_WME|MY_ZEROFILL)))) - return 0; - con->free_me=1; - con->net_buf=(char*)con+sizeof(*con); - } - else - { - bzero((char*)con,sizeof(*con)); - if (!(con->net_buf=my_malloc(net_buf_size,MYF(0)))) - return 0; - } - con->net_buf_pos=con->net_data_end=con->net_buf; - con->net_buf_size=net_buf_size; - return con; -} - -MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con, - const char* host, - const char* user, - const char* passwd, - unsigned int port) -{ - my_socket sock; - struct sockaddr_in sock_addr; - in_addr_t ip_addr; - char msg_buf[MAX_MYSQL_MANAGER_MSG]; - int msg_len; - Vio* vio; - my_bool not_used; - - if (!host) - host="localhost"; - if (!user) - user="root"; - if (!passwd) - passwd=""; - - if ((sock=(my_socket)socket(AF_INET,SOCK_STREAM,0)) == INVALID_SOCKET) - { - con->last_errno=errno; - strmov(con->last_error,"Cannot create socket"); - goto err; - } - if (!(vio=vio_new(sock,VIO_TYPE_TCPIP,FALSE))) - { - con->last_errno=ENOMEM; - strmov(con->last_error,"Cannot create network I/O object"); - goto err; - } - vio_blocking(vio, TRUE, ¬_used); - my_net_init(&con->net,vio); - bzero((char*) &sock_addr,sizeof(sock_addr)); - sock_addr.sin_family = AF_INET; - if ((int) (ip_addr = inet_addr(host)) != (int) INADDR_NONE) - { - memcpy_fixed(&sock_addr.sin_addr,&ip_addr,sizeof(ip_addr)); - } - else - { - int tmp_errno; - struct hostent tmp_hostent,*hp; - char buff2[GETHOSTBYNAME_BUFF_SIZE]; - hp = my_gethostbyname_r(host,&tmp_hostent,buff2,sizeof(buff2), - &tmp_errno); - if (!hp) - { - con->last_errno=tmp_errno; - sprintf(con->last_error,"Could not resolve host '%-.64s'",host); - my_gethostbyname_r_free(); - goto err; - } - memcpy(&sock_addr.sin_addr,hp->h_addr, (size_t) hp->h_length); - my_gethostbyname_r_free(); - } - sock_addr.sin_port = (ushort) htons((ushort) port); - if (my_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr), - 0)) - { - con->last_errno=errno; - sprintf(con->last_error ,"Could not connect to %-.64s", host); - goto err; - } - /* read the greating */ - if (my_net_read(&con->net) == packet_error) - { - con->last_errno=errno; - strmov(con->last_error,"Read error on socket"); - goto err; - } - sprintf(msg_buf,"%-.16s %-.16s\n",user,passwd); - msg_len=strlen(msg_buf); - if (my_net_write(&con->net,(uchar*) msg_buf,msg_len) || net_flush(&con->net)) - { - con->last_errno=con->net.last_errno; - strmov(con->last_error,"Write error on socket"); - goto err; - } - if (my_net_read(&con->net) == packet_error) - { - con->last_errno=errno; - strmov(con->last_error,"Read error on socket"); - goto err; - } - if ((con->cmd_status=atoi((char*) con->net.read_pos)) != MANAGER_OK) - { - strmov(con->last_error,"Access denied"); - goto err; - } - if (!my_multi_malloc(MYF(0), &con->host, (uint)strlen(host)+1, - &con->user, (uint)strlen(user)+1, - &con->passwd, (uint)strlen(passwd)+1, - NullS)) - { - con->last_errno=ENOMEM; - strmov(con->last_error,"Out of memory"); - goto err; - } - strmov(con->host,host); - strmov(con->user,user); - strmov(con->passwd,passwd); - return con; - -err: - { - my_bool free_me=con->free_me; - con->free_me=0; - mysql_manager_close(con); - con->free_me=free_me; - } - return 0; -} - -void STDCALL mysql_manager_close(MYSQL_MANAGER* con) -{ - /* - No need to free con->user and con->passwd, because they were - allocated in my_multimalloc() along with con->host, freeing - con->hosts frees the whole block - */ - my_free((uchar*)con->host,MYF(MY_ALLOW_ZERO_PTR)); - net_end(&con->net); - if (con->free_me) - my_free((uchar*)con,MYF(0)); -} - - -int STDCALL mysql_manager_command(MYSQL_MANAGER* con,const char* cmd, - int cmd_len) -{ - if (!cmd_len) - cmd_len=strlen(cmd); - if (my_net_write(&con->net,(const uchar*)cmd,cmd_len) || net_flush(&con->net)) - { - con->last_errno=errno; - strmov(con->last_error,"Write error on socket"); - return 1; - } - con->eof=0; - return 0; -} - - -int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, char* res_buf, - int res_buf_size) -{ - char* res_buf_end=res_buf+res_buf_size; - char* net_buf=(char*) con->net.read_pos, *net_buf_end; - int res_buf_shift=RES_BUF_SHIFT; - ulong num_bytes; - - if (res_buf_sizelast_errno=ENOMEM; - strmov(con->last_error,"Result buffer too small"); - return 1; - } - - if ((num_bytes=my_net_read(&con->net)) == packet_error) - { - con->last_errno=errno; - strmov(con->last_error,"socket read failed"); - return 1; - } - - net_buf_end=net_buf+num_bytes; - - if ((con->eof=(net_buf[3]==' '))) - res_buf_shift--; - net_buf+=res_buf_shift; - res_buf_end[-1]=0; - for (;net_bufssl_capath, MYF(MY_ALLOW_ZERO_PTR)); options->ssl_capath = my_strdup(opt_arg, MYF(MY_WME)); break; - case 26: /* ssl_cipher */ + case 23: /* ssl_cipher */ my_free(options->ssl_cipher, MYF(MY_ALLOW_ZERO_PTR)); options->ssl_cipher= my_strdup(opt_arg, MYF(MY_WME)); break; @@ -1191,7 +1190,7 @@ void mysql_read_default_options(struct st_mysql_options *options, case 14: case 15: case 16: - case 26: + case 23: break; #endif /* HAVE_OPENSSL */ case 17: /* charset-lib */ @@ -1214,24 +1213,11 @@ void mysql_read_default_options(struct st_mysql_options *options, case 22: options->client_flag&= ~CLIENT_LOCAL_FILES; break; - case 23: /* replication probe */ -#ifndef TO_BE_DELETED - options->rpl_probe= 1; -#endif - break; - case 24: /* enable-reads-from-master */ - options->no_master_reads= 0; - break; - case 25: /* repl-parse-query */ -#ifndef TO_BE_DELETED - options->rpl_parse= 1; -#endif - break; - case 27: + case 24: /* max-allowed-packet */ if (opt_arg) options->max_allowed_packet= atoi(opt_arg); break; - case 28: /* protocol */ + case 25: /* protocol */ if ((options->protocol= find_type(opt_arg, &sql_protocol_typelib,0)) <= 0) { @@ -1239,24 +1225,24 @@ void mysql_read_default_options(struct st_mysql_options *options, exit(1); } break; - case 29: /* shared_memory_base_name */ + case 26: /* shared_memory_base_name */ #ifdef HAVE_SMEM if (options->shared_memory_base_name != def_shared_memory_base_name) my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME)); #endif break; - case 30: + case 27: /* multi-results */ options->client_flag|= CLIENT_MULTI_RESULTS; break; - case 31: - case 32: + case 28: /* multi-statements */ + case 29: /* multi-queries */ options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS; break; - case 33: /* secure-auth */ + case 30: /* secure-auth */ options->secure_auth= TRUE; break; - case 34: /* report-data-truncation */ + case 31: /* report-data-truncation */ options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1; break; default: @@ -1583,16 +1569,8 @@ mysql_init(MYSQL *mysql) else bzero((char*) (mysql), sizeof(*(mysql))); mysql->options.connect_timeout= CONNECT_TIMEOUT; - mysql->last_used_con= mysql->next_slave= mysql->master = mysql; mysql->charset=default_client_charset_info; strmov(mysql->net.sqlstate, not_error_sqlstate); - /* - By default, we are a replication pivot. The caller must reset it - after we return if this is not the case. - */ -#ifndef TO_BE_DELETED - mysql->rpl_pivot = 1; -#endif /* Only enable LOAD DATA INFILE by default if configured with @@ -2533,11 +2511,6 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, mysql->reconnect=reconnect; } -#ifndef TO_BE_DELETED - if (mysql->options.rpl_probe && mysql_rpl_probe(mysql)) - goto error; -#endif - DBUG_PRINT("exit", ("Mysql handler: 0x%lx", (long) mysql)); reset_sigpipe(mysql); DBUG_RETURN(mysql); @@ -2559,28 +2532,6 @@ error: } -/* needed when we move MYSQL structure to a different address */ - -#ifndef TO_BE_DELETED -static void mysql_fix_pointers(MYSQL* mysql, MYSQL* old_mysql) -{ - MYSQL *tmp, *tmp_prev; - if (mysql->master == old_mysql) - mysql->master= mysql; - if (mysql->last_used_con == old_mysql) - mysql->last_used_con= mysql; - if (mysql->last_used_slave == old_mysql) - mysql->last_used_slave= mysql; - for (tmp_prev = mysql, tmp = mysql->next_slave; - tmp != old_mysql;tmp = tmp->next_slave) - { - tmp_prev= tmp; - } - tmp_prev->next_slave= mysql; -} -#endif - - my_bool mysql_reconnect(MYSQL *mysql) { MYSQL tmp_mysql; @@ -2599,8 +2550,7 @@ my_bool mysql_reconnect(MYSQL *mysql) mysql_init(&tmp_mysql); tmp_mysql.options= mysql->options; tmp_mysql.options.my_cnf_file= tmp_mysql.options.my_cnf_group= 0; - tmp_mysql.rpl_pivot= mysql->rpl_pivot; - + if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd, mysql->db, mysql->port, mysql->unix_socket, mysql->client_flag | CLIENT_REMEMBER_OPTIONS)) @@ -2634,7 +2584,6 @@ my_bool mysql_reconnect(MYSQL *mysql) mysql->free_me=0; mysql_close(mysql); *mysql=tmp_mysql; - mysql_fix_pointers(mysql, &tmp_mysql); /* adjust connection pointers */ net_clear(&mysql->net, 1); mysql->affected_rows= ~(my_ulonglong) 0; DBUG_RETURN(0); @@ -2812,23 +2761,6 @@ void STDCALL mysql_close(MYSQL *mysql) mysql_close_free_options(mysql); mysql_close_free(mysql); mysql_detach_stmt_list(&mysql->stmts, "mysql_close"); -#ifndef TO_BE_DELETED - /* free/close slave list */ - if (mysql->rpl_pivot) - { - MYSQL* tmp; - for (tmp = mysql->next_slave; tmp != mysql; ) - { - /* trick to avoid following freed pointer */ - MYSQL* tmp1 = tmp->next_slave; - mysql_close(tmp); - tmp = tmp1; - } - mysql->rpl_pivot=0; - } -#endif - if (mysql != mysql->master) - mysql_close(mysql->master); #ifndef MYSQL_SERVER if (mysql->thd) (*mysql->methods->free_embedded_thd)(mysql); @@ -2848,12 +2780,6 @@ static my_bool cli_read_query_result(MYSQL *mysql) ulong length; DBUG_ENTER("cli_read_query_result"); - /* - Read from the connection which we actually used, which - could differ from the original connection if we have slaves - */ - mysql = mysql->last_used_con; - if ((length = cli_safe_read(mysql)) == packet_error) DBUG_RETURN(1); free_old_query(mysql); /* Free old result */ @@ -2928,23 +2854,6 @@ int STDCALL mysql_send_query(MYSQL* mysql, const char* query, ulong length) { DBUG_ENTER("mysql_send_query"); - DBUG_PRINT("enter",("rpl_parse: %d rpl_pivot: %d", - mysql->options.rpl_parse, mysql->rpl_pivot)); -#ifndef TO_BE_DELETED - if (mysql->options.rpl_parse && mysql->rpl_pivot) - { - switch (mysql_rpl_query_type(query, length)) { - case MYSQL_RPL_MASTER: - DBUG_RETURN(mysql_master_send_query(mysql, query, length)); - case MYSQL_RPL_SLAVE: - DBUG_RETURN(mysql_slave_send_query(mysql, query, length)); - case MYSQL_RPL_ADMIN: - break; /* fall through */ - } - } - mysql->last_used_con = mysql; -#endif - DBUG_RETURN(simple_command(mysql, COM_QUERY, (uchar*) query, length, 1)); } @@ -2971,8 +2880,7 @@ MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql) { MYSQL_RES *result; DBUG_ENTER("mysql_store_result"); - /* read from the actually used connection */ - mysql = mysql->last_used_con; + if (!mysql->fields) DBUG_RETURN(0); if (mysql->status != MYSQL_STATUS_GET_RESULT) @@ -3027,8 +2935,6 @@ static MYSQL_RES * cli_use_result(MYSQL *mysql) MYSQL_RES *result; DBUG_ENTER("cli_use_result"); - mysql = mysql->last_used_con; - if (!mysql->fields) DBUG_RETURN(0); if (mysql->status != MYSQL_STATUS_GET_RESULT) diff --git a/sql/Makefile.am b/sql/Makefile.am index 600a6117ebf..d4c79851904 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -110,7 +110,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ sql_plugin.h authors.h event_parse_data.h \ event_data_objects.h event_scheduler.h \ sql_partition.h partition_info.h partition_element.h \ - contributors.h sql_servers.h sql_signal.h + contributors.h sql_servers.h sql_signal.h records.h mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \ diff --git a/sql/handler.h b/sql/handler.h index ed5cc952b5d..f055af218b3 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -581,6 +581,7 @@ struct handler_iterator { void *buffer; }; +class handler; /* handlerton is a singleton structure - one instance per storage engine - to provide access to storage engine functionality that works on the @@ -1152,7 +1153,7 @@ public: virtual ~handler(void) { DBUG_ASSERT(locked == FALSE); - /* TODO: DBUG_ASSERT(inited == NONE); */ + DBUG_ASSERT(inited == NONE); } virtual handler *clone(MEM_ROOT *mem_root); /** This is called after create to allow us to set up cached variables */ diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index da651cec70c..d16710f6660 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1863,7 +1863,8 @@ void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row) DBUG_ASSERT(0); } -int init_read_record_seq(JOIN_TAB *tab); +int read_first_record_seq(JOIN_TAB *tab); +int rr_sequential(READ_RECORD *info); int join_read_always_key_or_null(JOIN_TAB *tab); int join_read_next_same_or_null(READ_RECORD *info); @@ -1945,7 +1946,8 @@ int subselect_single_select_engine::exec() /* Change the access method to full table scan */ tab->save_read_first_record= tab->read_first_record; tab->save_read_record= tab->read_record.read_record; - tab->read_first_record= init_read_record_seq; + tab->read_record.read_record= rr_sequential; + tab->read_first_record= read_first_record_seq; tab->read_record.record= tab->table->record[0]; tab->read_record.thd= join->thd; tab->read_record.ref_length= tab->table->file->ref_length; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 3a7a0e3bdd7..cac647a0d03 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -878,6 +878,7 @@ bool general_log_write(THD *thd, enum enum_server_command command, #include "tztime.h" #ifdef MYSQL_SERVER #include "sql_servers.h" +#include "records.h" #include "opt_range.h" #ifdef HAVE_QUERY_CACHE @@ -2235,12 +2236,6 @@ longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, int test_if_number(char *str,int *res,bool allow_wildcards); void change_byte(uchar *,uint,char,char); -void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, - SQL_SELECT *select, int use_record_cache, - bool print_errors, bool disable_rr_cache); -void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, - bool print_error, uint idx); -void end_read_record(READ_RECORD *info); ha_rows filesort(THD *thd, TABLE *form,struct st_sort_field *sortorder, uint s_length, SQL_SELECT *select, ha_rows max_rows, bool sort_positions, diff --git a/sql/records.cc b/sql/records.cc index 9e040de3fda..9b5ea40478e 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -13,6 +13,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifdef USE_PRAGMA_INTERFACE +#pragma implementation /* gcc class implementation */ +#endif /** @file @@ -21,8 +24,10 @@ Functions for easy reading of records, possible through a cache */ +#include "records.h" #include "mysql_priv.h" + static int rr_quick(READ_RECORD *info); int rr_sequential(READ_RECORD *info); static int rr_from_tempfile(READ_RECORD *info); diff --git a/sql/records.h b/sql/records.h new file mode 100644 index 00000000000..9207a05f826 --- /dev/null +++ b/sql/records.h @@ -0,0 +1,75 @@ +#ifndef SQL_RECORDS_H +#define SQL_RECORDS_H +/* Copyright (C) 2008 Sun/MySQL + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifdef USE_PRAGMA_INTERFACE +#pragma interface /* gcc class implementation */ +#endif +#include /* for uint typedefs */ + +struct st_join_table; +class handler; +struct TABLE; +class THD; +class SQL_SELECT; + +/** + A context for reading through a single table using a chosen access method: + index read, scan, etc, use of cache, etc. + + Use by: + READ_RECORD read_record; + init_read_record(&read_record, ...); + while (read_record.read_record()) + { + ... + } + end_read_record(); +*/ + +struct READ_RECORD +{ + typedef int (*Read_func)(READ_RECORD*); + typedef int (*Setup_func)(struct st_join_table*); + + TABLE *table; /* Head-form */ + handler *file; + TABLE **forms; /* head and ref forms */ + Read_func read_record; + THD *thd; + SQL_SELECT *select; + uint cache_records; + uint ref_length,struct_length,reclength,rec_cache_size,error_offset; + uint index; + uchar *ref_pos; /* pointer to form->refpos */ + uchar *record; + uchar *rec_buf; /* to read field values after filesort */ + uchar *cache,*cache_pos,*cache_end,*read_positions; + struct st_io_cache *io_cache; + bool print_error, ignore_not_found_rows; + +public: + READ_RECORD() {} +}; + +void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, + SQL_SELECT *select, int use_record_cache, + bool print_errors, bool disable_rr_cache); +void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, + bool print_error, uint idx); +void end_read_record(READ_RECORD *info); + +#endif /* SQL_RECORDS_H */ diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 0cf3d37c230..c013037eef4 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1958,15 +1958,19 @@ sp_head::execute_procedure(THD *thd, List *args) } } - /* - Okay, got values for all arguments. Close tables that might be used by - arguments evaluation. If arguments evaluation required prelocking mode, + /* + Okay, got values for all arguments. Close tables that might be used by + arguments evaluation. If arguments evaluation required prelocking mode, we'll leave it here. */ if (!thd->in_sub_stmt) { thd->lex->unit.cleanup(); - close_thread_tables(thd); + + thd_proc_info(thd, "closing tables"); + close_thread_tables(thd); + thd_proc_info(thd, 0); + thd->rollback_item_tree_changes(); } diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 1252d32ef99..fc853af65a8 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -2114,10 +2114,10 @@ ulong Query_cache::init_cache() file system) and so should use case insensitive collation for comparison. */ - VOID(hash_init(&tables, - lower_case_table_names ? &my_charset_bin : - files_charset_info, - def_table_hash_size, 0, 0,query_cache_table_get_key, 0, 0)); + VOID(my_hash_init(&tables, + lower_case_table_names ? &my_charset_bin : + files_charset_info, + def_table_hash_size, 0, 0,query_cache_table_get_key, 0, 0)); #endif queries_in_cache = 0; diff --git a/sql/sql_class.h b/sql/sql_class.h index cd063b1db3a..558de19b7af 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -280,6 +280,27 @@ public: LEX_COLUMN (const String& x,const uint& y ): column (x),rights (y) {} }; +/** + Query_cache_tls -- query cache thread local data. +*/ + +struct Query_cache_block; + +struct Query_cache_tls +{ + /* + 'first_query_block' should be accessed only via query cache + functions and methods to maintain proper locking. + */ + Query_cache_block *first_query_block; + void set_first_query_block(Query_cache_block *first_query_block_arg) + { + first_query_block= first_query_block_arg; + } + + Query_cache_tls() :first_query_block(NULL) {} +}; + /* SIGNAL / RESIGNAL / GET DIAGNOSTICS */ /** @@ -315,27 +336,6 @@ typedef enum enum_diag_condition_item_name */ extern const LEX_STRING Diag_condition_item_names[]; -/** - Query_cache_tls -- query cache thread local data. -*/ - -class Query_cache_block; - -struct Query_cache_tls -{ - /* - 'first_query_block' should be accessed only via query cache - functions and methods to maintain proper locking. - */ - Query_cache_block *first_query_block; - void set_first_query_block(Query_cache_block *first_query_block_arg) - { - first_query_block= first_query_block_arg; - } - - Query_cache_tls() :first_query_block(NULL) {} -}; - #include "sql_lex.h" /* Must be here */ class Delayed_insert; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6426363d7a0..9e94bd59bae 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -991,13 +991,13 @@ JOIN::optimize() } if (const_tables && !thd->locked_tables && !(select_options & SELECT_NO_UNLOCK)) - mysql_unlock_some_tables(thd, table, const_tables); + mysql_unlock_some_tables(thd, all_tables, const_tables); if (!conds && outer_join) { /* Handle the case where we have an OUTER JOIN without a WHERE */ conds=new Item_int((longlong) 1,1); // Always true } - select= make_select(*table, const_table_map, + select= make_select(*all_tables, const_table_map, const_table_map, conds, 1, &error); if (error) { /* purecov: inspected */ @@ -2905,7 +2905,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds, join->join_tab=stat; join->map2table=stat_ref; - join->table= join->all_tables=table_vector; + join->all_tables= table_vector; join->const_tables=const_count; join->found_const_table_map=found_const_table_map; @@ -5595,7 +5595,7 @@ get_best_combination(JOIN *join) { TABLE *form; *j= *join->best_positions[tablenr].table; - form=join->table[tablenr]=j->table; + form=join->all_tables[tablenr]=j->table; used_tables|= form->map; form->reginfo.join_tab=j; if (!*j->on_expr_ref) @@ -5867,7 +5867,7 @@ JOIN::make_simple_join(JOIN *parent, TABLE *tmp_table) DBUG_RETURN(TRUE); /* purecov: inspected */ join_tab= parent->join_tab_reexec; - table= &parent->table_reexec[0]; parent->table_reexec[0]= tmp_table; + parent->table_reexec[0]= tmp_table; tables= 1; const_tables= 0; const_table_map= 0; @@ -6899,24 +6899,23 @@ void JOIN::cleanup(bool full) { DBUG_ENTER("JOIN::cleanup"); - if (table) + if (all_tables) { JOIN_TAB *tab,*end; /* Only a sorted table may be cached. This sorted table is always the - first non const table in join->table + first non const table in join->all_tables */ if (tables > const_tables) // Test for not-const tables { - free_io_cache(table[const_tables]); - filesort_free_buffers(table[const_tables],full); + free_io_cache(all_tables[const_tables]); + filesort_free_buffers(all_tables[const_tables],full); } if (full) { for (tab= join_tab, end= tab+tables; tab != end; tab++) tab->cleanup(); - table= 0; } else { @@ -7245,7 +7244,7 @@ static void clear_tables(JOIN *join) are not re-calculated. */ for (uint i=join->const_tables ; i < join->tables ; i++) - mark_as_null_row(join->table[i]); // All fields are NULL + mark_as_null_row(join->all_tables[i]); // All fields are NULL } /***************************************************************************** @@ -10995,26 +10994,7 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) if (error == NESTED_LOOP_NO_MORE_ROWS) error= NESTED_LOOP_OK; - if (error == NESTED_LOOP_OK) - { - /* - Sic: this branch works even if rc != 0, e.g. when - send_data above returns an error. - */ - if (!table) // If sending data to client - { - /* - The following will unlock all cursors if the command wasn't an - update command - */ - join->join_free(); // Unlock all cursors - if (join->result->send_eof()) - rc= 1; // Don't send error - } - DBUG_PRINT("info",("%ld records output", (long) join->send_records)); - } - else - rc= -1; + if (table) { int tmp, new_errno= 0; @@ -11031,6 +11011,29 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) if (new_errno) table->file->print_error(new_errno,MYF(0)); } + else + { + /* + The following will unlock all cursors if the command wasn't an + update command + */ + join->join_free(); // Unlock all cursors + } + if (error == NESTED_LOOP_OK) + { + /* + Sic: this branch works even if rc != 0, e.g. when + send_data above returns an error. + */ + if (!table) // If sending data to client + { + if (join->result->send_eof()) + rc= 1; // Don't send error + } + DBUG_PRINT("info",("%ld records output", (long) join->send_records)); + } + else + rc= -1; #ifndef DBUG_OFF if (rc) { @@ -11878,10 +11881,8 @@ join_init_quick_read_record(JOIN_TAB *tab) } -int rr_sequential(READ_RECORD *info); -int init_read_record_seq(JOIN_TAB *tab) +int read_first_record_seq(JOIN_TAB *tab) { - tab->read_record.read_record= rr_sequential; if (tab->read_record.file->ha_rnd_init(1)) return 1; return (*tab->read_record.read_record)(&tab->read_record); diff --git a/sql/sql_select.h b/sql/sql_select.h index bb751c600ed..c725316f4dd 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -134,7 +134,6 @@ enum enum_nested_loop_state typedef enum_nested_loop_state (*Next_select_func)(JOIN *, struct st_join_table *, bool); -typedef int (*Read_record_func)(struct st_join_table *tab); Next_select_func setup_end_select_func(JOIN *join); @@ -162,7 +161,7 @@ typedef struct st_join_table { */ uint packed_info; - Read_record_func read_first_record; + READ_RECORD::Setup_func read_first_record; Next_select_func next_select; READ_RECORD read_record; /* @@ -170,8 +169,8 @@ typedef struct st_join_table { if it is executed by an alternative full table scan when the left operand of the subquery predicate is evaluated to NULL. */ - Read_record_func save_read_first_record;/* to save read_first_record */ - int (*save_read_record) (READ_RECORD *);/* to save read_record.read_record */ + READ_RECORD::Setup_func save_read_first_record;/* to save read_first_record */ + READ_RECORD::Read_func save_read_record;/* to save read_record.read_record */ double worst_seeks; key_map const_keys; /**< Keys with constant part */ key_map checked_keys; /**< Keys checked in find_best */ @@ -280,7 +279,7 @@ public: JOIN_TAB *join_tab,**best_ref; JOIN_TAB **map2table; ///< mapping between table indexes and JOIN_TABs JOIN_TAB *join_tab_save; ///< saved join_tab for subquery reexecution - TABLE **table,**all_tables,*sort_by_table; + TABLE **all_tables,*sort_by_table; uint tables,const_tables; uint send_group_parts; bool sort_and_group,first_record,full_join,group, no_field_update; @@ -427,7 +426,7 @@ public: select_result *result_arg) { join_tab= join_tab_save= 0; - table= 0; + all_tables= 0; tables= 0; const_tables= 0; join_list= 0; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 2bae6859a83..e6f9bb9e5e3 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -7477,7 +7477,7 @@ view_err: end_temporary: my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO), (ulong) (copied + deleted), (ulong) deleted, - (ulong) thd->cuted_fields); + (ulong) thd->warning_info->statement_warn_count()); my_ok(thd, copied + deleted, 0L, tmp_name); thd->some_tables_deleted=0; DBUG_RETURN(FALSE); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index f5c4b85e904..01a66a3a98b 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -833,7 +833,7 @@ int mysql_update(THD *thd, char buff[STRING_BUFFER_USUAL_SIZE]; my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated, - (ulong) thd->warning_info->statement_warn_count()); + (ulong) thd->warning_info->statement_warn_count()); thd->row_count_func= (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated; my_ok(thd, (ulong) thd->row_count_func, id, buff); diff --git a/sql/structs.h b/sql/structs.h index c668b056a99..2c8e1121edc 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -18,6 +18,7 @@ struct TABLE; class Field; +class THD; typedef struct st_date_time_format { uchar positions[8]; @@ -115,30 +116,6 @@ typedef struct st_reginfo { /* Extra info about reg */ } REGINFO; -struct st_read_record; /* For referense later */ -class SQL_SELECT; -class THD; -class handler; - -typedef struct st_read_record { /* Parameter to read_record */ - TABLE *table; /* Head-form */ - handler *file; - TABLE **forms; /* head and ref forms */ - int (*read_record)(struct st_read_record *); - THD *thd; - SQL_SELECT *select; - uint cache_records; - uint ref_length,struct_length,reclength,rec_cache_size,error_offset; - uint index; - uchar *ref_pos; /* pointer to form->refpos */ - uchar *record; - uchar *rec_buf; /* to read field values after filesort */ - uchar *cache,*cache_pos,*cache_end,*read_positions; - IO_CACHE *io_cache; - bool print_error, ignore_not_found_rows; -} READ_RECORD; - - /* Originally MySQL used MYSQL_TIME structure inside server only, but since 4.1 it's exported to user in the new client API. Define aliases for diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index cf39e306067..05be8b27a8b 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -2892,7 +2892,7 @@ int ha_federated::info(uint flag) } if (flag & HA_STATUS_AUTO) - stats.auto_increment_value= mysql->last_used_con->insert_id; + stats.auto_increment_value= mysql->insert_id; mysql_free_result(result);