Pull from mysql-next-mr-runtime.
This commit is contained in:
commit
519f1aee78
@ -259,8 +259,7 @@ enum enum_commands {
|
|||||||
Q_SEND, Q_REAP,
|
Q_SEND, Q_REAP,
|
||||||
Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN,
|
Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN,
|
||||||
Q_PING, Q_EVAL,
|
Q_PING, Q_EVAL,
|
||||||
Q_RPL_PROBE, Q_ENABLE_RPL_PARSE,
|
Q_EVAL_RESULT,
|
||||||
Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT,
|
|
||||||
Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
|
Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
|
||||||
Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
|
Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
|
||||||
Q_WAIT_FOR_SLAVE_TO_STOP,
|
Q_WAIT_FOR_SLAVE_TO_STOP,
|
||||||
@ -319,9 +318,6 @@ const char *command_names[]=
|
|||||||
"replace_column",
|
"replace_column",
|
||||||
"ping",
|
"ping",
|
||||||
"eval",
|
"eval",
|
||||||
"rpl_probe",
|
|
||||||
"enable_rpl_parse",
|
|
||||||
"disable_rpl_parse",
|
|
||||||
"eval_result",
|
"eval_result",
|
||||||
/* Enable/disable that the _query_ is logged to result file */
|
/* Enable/disable that the _query_ is logged to result file */
|
||||||
"enable_query_log",
|
"enable_query_log",
|
||||||
@ -661,14 +657,6 @@ public:
|
|||||||
LogFile log_file;
|
LogFile log_file;
|
||||||
LogFile progress_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,
|
void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
|
||||||
int len);
|
int len);
|
||||||
void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
|
void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
|
||||||
@ -3850,12 +3838,8 @@ int do_save_master_pos()
|
|||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
MYSQL *mysql = &cur_con->mysql;
|
MYSQL *mysql = &cur_con->mysql;
|
||||||
const char *query;
|
const char *query;
|
||||||
int rpl_parse;
|
|
||||||
DBUG_ENTER("do_save_master_pos");
|
DBUG_ENTER("do_save_master_pos");
|
||||||
|
|
||||||
rpl_parse = mysql_rpl_parse_enabled(mysql);
|
|
||||||
mysql_disable_rpl_parse(mysql);
|
|
||||||
|
|
||||||
#ifdef HAVE_NDB_BINLOG
|
#ifdef HAVE_NDB_BINLOG
|
||||||
/*
|
/*
|
||||||
Wait for ndb binlog to be up-to-date with all changes
|
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);
|
strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1);
|
||||||
master_pos.pos = strtoul(row[1], (char**) 0, 10);
|
master_pos.pos = strtoul(row[1], (char**) 0, 10);
|
||||||
mysql_free_result(res);
|
mysql_free_result(res);
|
||||||
|
|
||||||
if (rpl_parse)
|
|
||||||
mysql_enable_rpl_parse(mysql);
|
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
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
|
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)
|
if (!disable_result_log)
|
||||||
{
|
{
|
||||||
ulonglong UNINIT_VAR(affected_rows); /* Ok to be undef if 'disable_info' is set */
|
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
MYSQL_FIELD *fields= mysql_fetch_fields(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"
|
Need to call mysql_affected_rows() before the "new"
|
||||||
query to find the warnings
|
query to find the warnings.
|
||||||
*/
|
*/
|
||||||
if (!disable_info)
|
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
|
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);
|
dynstr_append_mem(ds, ds_warnings->str, ds_warnings->length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!disable_info)
|
|
||||||
append_info(ds, affected_rows, mysql_info(mysql));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res)
|
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)
|
if (!disable_warnings)
|
||||||
{
|
{
|
||||||
/* Get the warnings from execute */
|
/* 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:
|
end:
|
||||||
@ -7761,9 +7717,6 @@ int main(int argc, char **argv)
|
|||||||
case Q_DISCONNECT:
|
case Q_DISCONNECT:
|
||||||
case Q_DIRTY_CLOSE:
|
case Q_DIRTY_CLOSE:
|
||||||
do_close_connection(command); break;
|
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_ENABLE_QUERY_LOG: disable_query_log=0; break;
|
||||||
case Q_DISABLE_QUERY_LOG: disable_query_log=1; break;
|
case Q_DISABLE_QUERY_LOG: disable_query_log=1; break;
|
||||||
case Q_ENABLE_ABORT_ON_ERROR: abort_on_error=1; break;
|
case Q_ENABLE_ABORT_ON_ERROR: abort_on_error=1; break;
|
||||||
|
125
include/mysql.h
125
include/mysql.h
@ -188,24 +188,10 @@ struct st_mysql_options {
|
|||||||
unsigned long max_allowed_packet;
|
unsigned long max_allowed_packet;
|
||||||
my_bool use_ssl; /* if to use SSL or not */
|
my_bool use_ssl; /* if to use SSL or not */
|
||||||
my_bool compress,named_pipe;
|
my_bool compress,named_pipe;
|
||||||
/*
|
my_bool unused1;
|
||||||
On connect, find out the replication role of the server, and
|
my_bool unused2;
|
||||||
establish connections to all the peers
|
my_bool unused3;
|
||||||
*/
|
my_bool unused4;
|
||||||
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
|
|
||||||
enum mysql_option methods_to_use;
|
enum mysql_option methods_to_use;
|
||||||
char *client_ip;
|
char *client_ip;
|
||||||
/* Refuse client connecting to server if it uses old (pre-4.1.1) protocol */
|
/* 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_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET,
|
||||||
MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY
|
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
|
typedef struct character_set
|
||||||
{
|
{
|
||||||
@ -285,21 +262,8 @@ typedef struct st_mysql
|
|||||||
|
|
||||||
/* session-wide random string */
|
/* session-wide random string */
|
||||||
char scramble[SCRAMBLE_LENGTH+1];
|
char scramble[SCRAMBLE_LENGTH+1];
|
||||||
|
my_bool unused1;
|
||||||
/*
|
void *unused2, *unused3, *unused4, *unused5;
|
||||||
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;
|
|
||||||
|
|
||||||
LIST *stmts; /* list of all statements */
|
LIST *stmts; /* list of all statements */
|
||||||
const struct st_mysql_methods *methods;
|
const struct st_mysql_methods *methods;
|
||||||
@ -333,35 +297,12 @@ typedef struct st_mysql_res {
|
|||||||
void *extension;
|
void *extension;
|
||||||
} MYSQL_RES;
|
} 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)
|
#if !defined(MYSQL_SERVER) && !defined(MYSQL_CLIENT)
|
||||||
#define MYSQL_CLIENT
|
#define MYSQL_CLIENT
|
||||||
#endif
|
#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
|
typedef struct st_mysql_parameters
|
||||||
{
|
{
|
||||||
unsigned long *p_max_allowed_packet;
|
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_store_result(MYSQL *mysql);
|
||||||
MYSQL_RES * STDCALL mysql_use_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,
|
void STDCALL mysql_get_character_set_info(MYSQL *mysql,
|
||||||
MY_CHARSET_INFO *charset);
|
MY_CHARSET_INFO *charset);
|
||||||
|
|
||||||
@ -485,37 +416,6 @@ mysql_set_local_infile_handler(MYSQL *mysql,
|
|||||||
void
|
void
|
||||||
mysql_set_local_infile_default(MYSQL *mysql);
|
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,
|
int STDCALL mysql_shutdown(MYSQL *mysql,
|
||||||
enum mysql_enum_shutdown_level
|
enum mysql_enum_shutdown_level
|
||||||
shutdown_level);
|
shutdown_level);
|
||||||
@ -562,18 +462,6 @@ void STDCALL mysql_debug(const char *debug);
|
|||||||
void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
|
void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
|
||||||
unsigned int STDCALL mysql_thread_safe(void);
|
unsigned int STDCALL mysql_thread_safe(void);
|
||||||
my_bool STDCALL mysql_embedded(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);
|
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);
|
const char *user, const char *passwd);
|
||||||
int STDCALL mysql_create_db(MYSQL *mysql, const char *DB);
|
int STDCALL mysql_create_db(MYSQL *mysql, const char *DB);
|
||||||
int STDCALL mysql_drop_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
|
#endif
|
||||||
#define HAVE_MYSQL_REAL_CONNECT
|
#define HAVE_MYSQL_REAL_CONNECT
|
||||||
|
|
||||||
|
@ -277,10 +277,10 @@ struct st_mysql_options {
|
|||||||
unsigned long max_allowed_packet;
|
unsigned long max_allowed_packet;
|
||||||
my_bool use_ssl;
|
my_bool use_ssl;
|
||||||
my_bool compress,named_pipe;
|
my_bool compress,named_pipe;
|
||||||
my_bool rpl_probe;
|
my_bool unused1;
|
||||||
my_bool rpl_parse;
|
my_bool unused2;
|
||||||
my_bool no_master_reads;
|
my_bool unused3;
|
||||||
my_bool separate_thread;
|
my_bool unused4;
|
||||||
enum mysql_option methods_to_use;
|
enum mysql_option methods_to_use;
|
||||||
char *client_ip;
|
char *client_ip;
|
||||||
my_bool secure_auth;
|
my_bool secure_auth;
|
||||||
@ -301,10 +301,6 @@ enum mysql_protocol_type
|
|||||||
MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET,
|
MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET,
|
||||||
MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY
|
MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY
|
||||||
};
|
};
|
||||||
enum mysql_rpl_type
|
|
||||||
{
|
|
||||||
MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN
|
|
||||||
};
|
|
||||||
typedef struct character_set
|
typedef struct character_set
|
||||||
{
|
{
|
||||||
unsigned int number;
|
unsigned int number;
|
||||||
@ -344,10 +340,8 @@ typedef struct st_mysql
|
|||||||
my_bool free_me;
|
my_bool free_me;
|
||||||
my_bool reconnect;
|
my_bool reconnect;
|
||||||
char scramble[20 +1];
|
char scramble[20 +1];
|
||||||
my_bool rpl_pivot;
|
my_bool unused1;
|
||||||
struct st_mysql* master, *next_slave;
|
void *unused2, *unused3, *unused4, *unused5;
|
||||||
struct st_mysql* last_used_slave;
|
|
||||||
struct st_mysql* last_used_con;
|
|
||||||
LIST *stmts;
|
LIST *stmts;
|
||||||
const struct st_mysql_methods *methods;
|
const struct st_mysql_methods *methods;
|
||||||
void *thd;
|
void *thd;
|
||||||
@ -371,20 +365,6 @@ typedef struct st_mysql_res {
|
|||||||
my_bool unbuffered_fetch_cancelled;
|
my_bool unbuffered_fetch_cancelled;
|
||||||
void *extension;
|
void *extension;
|
||||||
} MYSQL_RES;
|
} 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
|
typedef struct st_mysql_parameters
|
||||||
{
|
{
|
||||||
unsigned long *p_max_allowed_packet;
|
unsigned long *p_max_allowed_packet;
|
||||||
@ -437,14 +417,6 @@ int mysql_real_query(MYSQL *mysql, const char *q,
|
|||||||
unsigned long length);
|
unsigned long length);
|
||||||
MYSQL_RES * mysql_store_result(MYSQL *mysql);
|
MYSQL_RES * mysql_store_result(MYSQL *mysql);
|
||||||
MYSQL_RES * mysql_use_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,
|
void mysql_get_character_set_info(MYSQL *mysql,
|
||||||
MY_CHARSET_INFO *charset);
|
MY_CHARSET_INFO *charset);
|
||||||
void
|
void
|
||||||
@ -459,22 +431,6 @@ mysql_set_local_infile_handler(MYSQL *mysql,
|
|||||||
void *);
|
void *);
|
||||||
void
|
void
|
||||||
mysql_set_local_infile_default(MYSQL *mysql);
|
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,
|
int mysql_shutdown(MYSQL *mysql,
|
||||||
enum mysql_enum_shutdown_level
|
enum mysql_enum_shutdown_level
|
||||||
shutdown_level);
|
shutdown_level);
|
||||||
@ -521,18 +477,6 @@ void mysql_debug(const char *debug);
|
|||||||
void myodbc_remove_escape(MYSQL *mysql,char *name);
|
void myodbc_remove_escape(MYSQL *mysql,char *name);
|
||||||
unsigned int mysql_thread_safe(void);
|
unsigned int mysql_thread_safe(void);
|
||||||
my_bool mysql_embedded(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);
|
my_bool mysql_read_query_result(MYSQL *mysql);
|
||||||
enum enum_mysql_stmt_state
|
enum enum_mysql_stmt_state
|
||||||
{
|
{
|
||||||
|
@ -408,10 +408,6 @@ void my_net_set_write_timeout(NET *net, uint timeout);
|
|||||||
void my_net_set_read_timeout(NET *net, uint timeout);
|
void my_net_set_read_timeout(NET *net, uint timeout);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
The following function is not meant for normal usage
|
|
||||||
Currently it's used internally by manager.c
|
|
||||||
*/
|
|
||||||
struct sockaddr;
|
struct sockaddr;
|
||||||
int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
|
int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
|
||||||
unsigned int timeout);
|
unsigned int timeout);
|
||||||
|
@ -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
|
../mysys/hash.c ../mysys/my_sleep.c ../mysys/default_modify.c
|
||||||
get_password.c ../strings/int2str.c ../strings/is_prefix.c
|
get_password.c ../strings/int2str.c ../strings/is_prefix.c
|
||||||
libmysql.c ../mysys/list.c ../strings/llstr.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_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_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
|
../mysys/mf_pack.c ../mysys/mf_path.c ../mysys/mf_tempfile.c ../mysys/mf_unixpath.c
|
||||||
|
@ -31,7 +31,7 @@ pkglib_LTLIBRARIES = $(target)
|
|||||||
noinst_PROGRAMS = conf_to_src
|
noinst_PROGRAMS = conf_to_src
|
||||||
|
|
||||||
|
|
||||||
target_sources = libmysql.c password.c manager.c \
|
target_sources = libmysql.c password.c \
|
||||||
get_password.c errmsg.c
|
get_password.c errmsg.c
|
||||||
|
|
||||||
mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \
|
mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \
|
||||||
|
@ -249,16 +249,6 @@ void STDCALL mysql_thread_end()
|
|||||||
#endif
|
#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
|
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
|
ARGSUSED
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
@ -333,305 +323,6 @@ my_pipe_sig_handler(int sig __attribute__((unused)))
|
|||||||
#endif
|
#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
|
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
|
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)
|
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)
|
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)
|
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)
|
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;
|
MYSQL_DATA *fields_data;
|
||||||
DBUG_ENTER("cli_read_prepare_result");
|
DBUG_ENTER("cli_read_prepare_result");
|
||||||
|
|
||||||
mysql= mysql->last_used_con;
|
|
||||||
if ((packet_length= cli_safe_read(mysql)) == packet_error)
|
if ((packet_length= cli_safe_read(mysql)) == packet_error)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
mysql->warning_count= 0;
|
mysql->warning_count= 0;
|
||||||
@ -2092,7 +1720,7 @@ static void alloc_stmt_fields(MYSQL_STMT *stmt)
|
|||||||
{
|
{
|
||||||
MYSQL_FIELD *fields, *field, *end;
|
MYSQL_FIELD *fields, *field, *end;
|
||||||
MEM_ROOT *alloc= &stmt->mem_root;
|
MEM_ROOT *alloc= &stmt->mem_root;
|
||||||
MYSQL *mysql= stmt->mysql->last_used_con;
|
MYSQL *mysql= stmt->mysql;
|
||||||
|
|
||||||
stmt->field_count= mysql->field_count;
|
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_ENTER("execute");
|
||||||
DBUG_DUMP("packet", (uchar *) packet, length);
|
DBUG_DUMP("packet", (uchar *) packet, length);
|
||||||
|
|
||||||
mysql->last_used_con= mysql;
|
|
||||||
int4store(buff, stmt->stmt_id); /* Send stmt id to server */
|
int4store(buff, stmt->stmt_id); /* Send stmt id to server */
|
||||||
buff[4]= (char) stmt->flags;
|
buff[4]= (char) stmt->flags;
|
||||||
int4store(buff+5, 1); /* iteration count */
|
int4store(buff+5, 1); /* iteration count */
|
||||||
@ -4689,7 +4316,6 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
net = &mysql->net;
|
net = &mysql->net;
|
||||||
mysql= mysql->last_used_con;
|
|
||||||
|
|
||||||
while ((pkt_len= cli_safe_read(mysql)) != packet_error)
|
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);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
mysql= mysql->last_used_con;
|
|
||||||
|
|
||||||
if (!stmt->field_count)
|
if (!stmt->field_count)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
@ -5193,8 +4817,7 @@ my_bool STDCALL mysql_more_results(MYSQL *mysql)
|
|||||||
my_bool res;
|
my_bool res;
|
||||||
DBUG_ENTER("mysql_more_results");
|
DBUG_ENTER("mysql_more_results");
|
||||||
|
|
||||||
res= ((mysql->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS) ?
|
res= ((mysql->server_status & SERVER_MORE_RESULTS_EXISTS) ? 1: 0);
|
||||||
1: 0);
|
|
||||||
DBUG_PRINT("exit",("More results exists ? %d", res));
|
DBUG_PRINT("exit",("More results exists ? %d", res));
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
@ -5216,7 +4839,7 @@ int STDCALL mysql_next_result(MYSQL *mysql)
|
|||||||
net_clear_error(&mysql->net);
|
net_clear_error(&mysql->net);
|
||||||
mysql->affected_rows= ~(my_ulonglong) 0;
|
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((*mysql->methods->next_result)(mysql));
|
||||||
|
|
||||||
DBUG_RETURN(-1); /* No more results */
|
DBUG_RETURN(-1); /* No more results */
|
||||||
|
@ -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 <my_global.h>
|
|
||||||
#if defined(THREAD)
|
|
||||||
#include <my_pthread.h> /* because of signal() */
|
|
||||||
#endif
|
|
||||||
#include "mysql.h"
|
|
||||||
#include "mysql_version.h"
|
|
||||||
#include "mysqld_error.h"
|
|
||||||
#include <my_sys.h>
|
|
||||||
#include <mysys_err.h>
|
|
||||||
#include <m_string.h>
|
|
||||||
#include <m_ctype.h>
|
|
||||||
#include <my_net.h>
|
|
||||||
#include <errmsg.h>
|
|
||||||
#include <violite.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#if defined(__NETWARE__)
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <sys/utsname.h>
|
|
||||||
#elif !defined( __WIN__)
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAVE_SYS_UN_H
|
|
||||||
# include <sys/un.h>
|
|
||||||
#endif
|
|
||||||
#include <netdb.h>
|
|
||||||
#ifdef HAVE_SELECT_H
|
|
||||||
# include <select.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SELECT_H
|
|
||||||
#include <sys/select.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/utsname.h>
|
|
||||||
#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_size<RES_BUF_SHIFT)
|
|
||||||
{
|
|
||||||
con->last_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_buf<net_buf_end && res_buf < res_buf_end;res_buf++,net_buf++)
|
|
||||||
{
|
|
||||||
if ((*res_buf=*net_buf) == '\r')
|
|
||||||
{
|
|
||||||
*res_buf=0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -639,3 +639,43 @@ CREATE TABLE t2(f1 CHAR(1));
|
|||||||
INSERT INTO t2 SELECT f1 FROM t1;
|
INSERT INTO t2 SELECT f1 FROM t1;
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
End of 5.0 tests.
|
End of 5.0 tests.
|
||||||
|
#
|
||||||
|
# Bug#34898 "mysql_info() reports 0 warnings while
|
||||||
|
# mysql_warning_count() reports 1"
|
||||||
|
# Check that the number of warnings reported by
|
||||||
|
# mysql_info() is correct.
|
||||||
|
#
|
||||||
|
drop table if exists t1;
|
||||||
|
create table t1 (data varchar(4) not null);
|
||||||
|
set sql_mode='error_for_division_by_zero';
|
||||||
|
#
|
||||||
|
# Demonstrate that the number of warnings matches
|
||||||
|
# the information in mysql_info().
|
||||||
|
#
|
||||||
|
insert t1 (data) values ('letter'), (1/0);
|
||||||
|
affected rows: 2
|
||||||
|
info: Records: 2 Duplicates: 0 Warnings: 3
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'data' at row 1
|
||||||
|
Warning 1365 Division by 0
|
||||||
|
Warning 1048 Column 'data' cannot be null
|
||||||
|
update t1 set data='envelope' where 1/0 or 1;
|
||||||
|
affected rows: 2
|
||||||
|
info: Rows matched: 2 Changed: 2 Warnings: 3
|
||||||
|
Warnings:
|
||||||
|
Warning 1365 Division by 0
|
||||||
|
Warning 1265 Data truncated for column 'data' at row 1
|
||||||
|
Warning 1265 Data truncated for column 'data' at row 2
|
||||||
|
insert t1 (data) values (default), (1/0), ('dead beef');
|
||||||
|
affected rows: 3
|
||||||
|
info: Records: 3 Duplicates: 0 Warnings: 4
|
||||||
|
Warnings:
|
||||||
|
Warning 1364 Field 'data' doesn't have a default value
|
||||||
|
Warning 1365 Division by 0
|
||||||
|
Warning 1048 Column 'data' cannot be null
|
||||||
|
Warning 1265 Data truncated for column 'data' at row 3
|
||||||
|
set sql_mode=default;
|
||||||
|
drop table t1;
|
||||||
|
#
|
||||||
|
# End of 5.4 tests
|
||||||
|
#
|
||||||
|
@ -181,21 +181,21 @@ affected rows: 2
|
|||||||
CREATE TABLE t1(sum INT, price FLOAT(24)) ENGINE=MyISAM;
|
CREATE TABLE t1(sum INT, price FLOAT(24)) ENGINE=MyISAM;
|
||||||
affected rows: 0
|
affected rows: 0
|
||||||
INSERT INTO t1 VALUES(myfunc_int(100), myfunc_double(50.00));
|
INSERT INTO t1 VALUES(myfunc_int(100), myfunc_double(50.00));
|
||||||
|
affected rows: 1
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1592 Statement may not be safe to log in statement format.
|
Note 1592 Statement may not be safe to log in statement format.
|
||||||
affected rows: 1
|
|
||||||
INSERT INTO t1 VALUES(myfunc_int(10), myfunc_double(5.00));
|
INSERT INTO t1 VALUES(myfunc_int(10), myfunc_double(5.00));
|
||||||
|
affected rows: 1
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1592 Statement may not be safe to log in statement format.
|
Note 1592 Statement may not be safe to log in statement format.
|
||||||
affected rows: 1
|
|
||||||
INSERT INTO t1 VALUES(myfunc_int(200), myfunc_double(25.00));
|
INSERT INTO t1 VALUES(myfunc_int(200), myfunc_double(25.00));
|
||||||
|
affected rows: 1
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1592 Statement may not be safe to log in statement format.
|
Note 1592 Statement may not be safe to log in statement format.
|
||||||
affected rows: 1
|
|
||||||
INSERT INTO t1 VALUES(myfunc_int(1), myfunc_double(500.00));
|
INSERT INTO t1 VALUES(myfunc_int(1), myfunc_double(500.00));
|
||||||
|
affected rows: 1
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1592 Statement may not be safe to log in statement format.
|
Note 1592 Statement may not be safe to log in statement format.
|
||||||
affected rows: 1
|
|
||||||
SELECT * FROM t1 ORDER BY sum;
|
SELECT * FROM t1 ORDER BY sum;
|
||||||
sum price
|
sum price
|
||||||
1 48.5
|
1 48.5
|
||||||
|
@ -499,3 +499,33 @@ DROP TABLE t1, t2;
|
|||||||
|
|
||||||
--echo End of 5.0 tests.
|
--echo End of 5.0 tests.
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#34898 "mysql_info() reports 0 warnings while
|
||||||
|
--echo # mysql_warning_count() reports 1"
|
||||||
|
--echo # Check that the number of warnings reported by
|
||||||
|
--echo # mysql_info() is correct.
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
create table t1 (data varchar(4) not null);
|
||||||
|
|
||||||
|
set sql_mode='error_for_division_by_zero';
|
||||||
|
--echo #
|
||||||
|
--echo # Demonstrate that the number of warnings matches
|
||||||
|
--echo # the information in mysql_info().
|
||||||
|
--echo #
|
||||||
|
--enable_info
|
||||||
|
insert t1 (data) values ('letter'), (1/0);
|
||||||
|
update t1 set data='envelope' where 1/0 or 1;
|
||||||
|
insert t1 (data) values (default), (1/0), ('dead beef');
|
||||||
|
--disable_info
|
||||||
|
|
||||||
|
set sql_mode=default;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 5.4 tests
|
||||||
|
--echo #
|
||||||
|
@ -1036,7 +1036,6 @@ static const char *default_options[]=
|
|||||||
"ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath",
|
"ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath",
|
||||||
"character-sets-dir", "default-character-set", "interactive-timeout",
|
"character-sets-dir", "default-character-set", "interactive-timeout",
|
||||||
"connect-timeout", "local-infile", "disable-local-infile",
|
"connect-timeout", "local-infile", "disable-local-infile",
|
||||||
"replication-probe", "enable-reads-from-master", "repl-parse-query",
|
|
||||||
"ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
|
"ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
|
||||||
"multi-results", "multi-statements", "multi-queries", "secure-auth",
|
"multi-results", "multi-statements", "multi-queries", "secure-auth",
|
||||||
"report-data-truncation",
|
"report-data-truncation",
|
||||||
@ -1182,7 +1181,7 @@ void mysql_read_default_options(struct st_mysql_options *options,
|
|||||||
my_free(options->ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
|
my_free(options->ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
|
||||||
options->ssl_capath = my_strdup(opt_arg, MYF(MY_WME));
|
options->ssl_capath = my_strdup(opt_arg, MYF(MY_WME));
|
||||||
break;
|
break;
|
||||||
case 26: /* ssl_cipher */
|
case 23: /* ssl_cipher */
|
||||||
my_free(options->ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
|
my_free(options->ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
|
||||||
options->ssl_cipher= my_strdup(opt_arg, MYF(MY_WME));
|
options->ssl_cipher= my_strdup(opt_arg, MYF(MY_WME));
|
||||||
break;
|
break;
|
||||||
@ -1191,7 +1190,7 @@ void mysql_read_default_options(struct st_mysql_options *options,
|
|||||||
case 14:
|
case 14:
|
||||||
case 15:
|
case 15:
|
||||||
case 16:
|
case 16:
|
||||||
case 26:
|
case 23:
|
||||||
break;
|
break;
|
||||||
#endif /* HAVE_OPENSSL */
|
#endif /* HAVE_OPENSSL */
|
||||||
case 17: /* charset-lib */
|
case 17: /* charset-lib */
|
||||||
@ -1214,24 +1213,11 @@ void mysql_read_default_options(struct st_mysql_options *options,
|
|||||||
case 22:
|
case 22:
|
||||||
options->client_flag&= ~CLIENT_LOCAL_FILES;
|
options->client_flag&= ~CLIENT_LOCAL_FILES;
|
||||||
break;
|
break;
|
||||||
case 23: /* replication probe */
|
case 24: /* max-allowed-packet */
|
||||||
#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:
|
|
||||||
if (opt_arg)
|
if (opt_arg)
|
||||||
options->max_allowed_packet= atoi(opt_arg);
|
options->max_allowed_packet= atoi(opt_arg);
|
||||||
break;
|
break;
|
||||||
case 28: /* protocol */
|
case 25: /* protocol */
|
||||||
if ((options->protocol= find_type(opt_arg,
|
if ((options->protocol= find_type(opt_arg,
|
||||||
&sql_protocol_typelib,0)) <= 0)
|
&sql_protocol_typelib,0)) <= 0)
|
||||||
{
|
{
|
||||||
@ -1239,24 +1225,24 @@ void mysql_read_default_options(struct st_mysql_options *options,
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 29: /* shared_memory_base_name */
|
case 26: /* shared_memory_base_name */
|
||||||
#ifdef HAVE_SMEM
|
#ifdef HAVE_SMEM
|
||||||
if (options->shared_memory_base_name != def_shared_memory_base_name)
|
if (options->shared_memory_base_name != def_shared_memory_base_name)
|
||||||
my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
|
my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME));
|
options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME));
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case 30:
|
case 27: /* multi-results */
|
||||||
options->client_flag|= CLIENT_MULTI_RESULTS;
|
options->client_flag|= CLIENT_MULTI_RESULTS;
|
||||||
break;
|
break;
|
||||||
case 31:
|
case 28: /* multi-statements */
|
||||||
case 32:
|
case 29: /* multi-queries */
|
||||||
options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS;
|
options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS;
|
||||||
break;
|
break;
|
||||||
case 33: /* secure-auth */
|
case 30: /* secure-auth */
|
||||||
options->secure_auth= TRUE;
|
options->secure_auth= TRUE;
|
||||||
break;
|
break;
|
||||||
case 34: /* report-data-truncation */
|
case 31: /* report-data-truncation */
|
||||||
options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
|
options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1583,16 +1569,8 @@ mysql_init(MYSQL *mysql)
|
|||||||
else
|
else
|
||||||
bzero((char*) (mysql), sizeof(*(mysql)));
|
bzero((char*) (mysql), sizeof(*(mysql)));
|
||||||
mysql->options.connect_timeout= CONNECT_TIMEOUT;
|
mysql->options.connect_timeout= CONNECT_TIMEOUT;
|
||||||
mysql->last_used_con= mysql->next_slave= mysql->master = mysql;
|
|
||||||
mysql->charset=default_client_charset_info;
|
mysql->charset=default_client_charset_info;
|
||||||
strmov(mysql->net.sqlstate, not_error_sqlstate);
|
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
|
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;
|
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));
|
DBUG_PRINT("exit", ("Mysql handler: 0x%lx", (long) mysql));
|
||||||
reset_sigpipe(mysql);
|
reset_sigpipe(mysql);
|
||||||
DBUG_RETURN(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)
|
my_bool mysql_reconnect(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
MYSQL tmp_mysql;
|
MYSQL tmp_mysql;
|
||||||
@ -2599,8 +2550,7 @@ my_bool mysql_reconnect(MYSQL *mysql)
|
|||||||
mysql_init(&tmp_mysql);
|
mysql_init(&tmp_mysql);
|
||||||
tmp_mysql.options= mysql->options;
|
tmp_mysql.options= mysql->options;
|
||||||
tmp_mysql.options.my_cnf_file= tmp_mysql.options.my_cnf_group= 0;
|
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,
|
if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
|
||||||
mysql->db, mysql->port, mysql->unix_socket,
|
mysql->db, mysql->port, mysql->unix_socket,
|
||||||
mysql->client_flag | CLIENT_REMEMBER_OPTIONS))
|
mysql->client_flag | CLIENT_REMEMBER_OPTIONS))
|
||||||
@ -2634,7 +2584,6 @@ my_bool mysql_reconnect(MYSQL *mysql)
|
|||||||
mysql->free_me=0;
|
mysql->free_me=0;
|
||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
*mysql=tmp_mysql;
|
*mysql=tmp_mysql;
|
||||||
mysql_fix_pointers(mysql, &tmp_mysql); /* adjust connection pointers */
|
|
||||||
net_clear(&mysql->net, 1);
|
net_clear(&mysql->net, 1);
|
||||||
mysql->affected_rows= ~(my_ulonglong) 0;
|
mysql->affected_rows= ~(my_ulonglong) 0;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
@ -2812,23 +2761,6 @@ void STDCALL mysql_close(MYSQL *mysql)
|
|||||||
mysql_close_free_options(mysql);
|
mysql_close_free_options(mysql);
|
||||||
mysql_close_free(mysql);
|
mysql_close_free(mysql);
|
||||||
mysql_detach_stmt_list(&mysql->stmts, "mysql_close");
|
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
|
#ifndef MYSQL_SERVER
|
||||||
if (mysql->thd)
|
if (mysql->thd)
|
||||||
(*mysql->methods->free_embedded_thd)(mysql);
|
(*mysql->methods->free_embedded_thd)(mysql);
|
||||||
@ -2848,12 +2780,6 @@ static my_bool cli_read_query_result(MYSQL *mysql)
|
|||||||
ulong length;
|
ulong length;
|
||||||
DBUG_ENTER("cli_read_query_result");
|
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)
|
if ((length = cli_safe_read(mysql)) == packet_error)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
free_old_query(mysql); /* Free old result */
|
free_old_query(mysql); /* Free old result */
|
||||||
@ -2928,23 +2854,6 @@ int STDCALL
|
|||||||
mysql_send_query(MYSQL* mysql, const char* query, ulong length)
|
mysql_send_query(MYSQL* mysql, const char* query, ulong length)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("mysql_send_query");
|
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));
|
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;
|
MYSQL_RES *result;
|
||||||
DBUG_ENTER("mysql_store_result");
|
DBUG_ENTER("mysql_store_result");
|
||||||
/* read from the actually used connection */
|
|
||||||
mysql = mysql->last_used_con;
|
|
||||||
if (!mysql->fields)
|
if (!mysql->fields)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
if (mysql->status != MYSQL_STATUS_GET_RESULT)
|
if (mysql->status != MYSQL_STATUS_GET_RESULT)
|
||||||
@ -3027,8 +2935,6 @@ static MYSQL_RES * cli_use_result(MYSQL *mysql)
|
|||||||
MYSQL_RES *result;
|
MYSQL_RES *result;
|
||||||
DBUG_ENTER("cli_use_result");
|
DBUG_ENTER("cli_use_result");
|
||||||
|
|
||||||
mysql = mysql->last_used_con;
|
|
||||||
|
|
||||||
if (!mysql->fields)
|
if (!mysql->fields)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
if (mysql->status != MYSQL_STATUS_GET_RESULT)
|
if (mysql->status != MYSQL_STATUS_GET_RESULT)
|
||||||
|
@ -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 \
|
sql_plugin.h authors.h event_parse_data.h \
|
||||||
event_data_objects.h event_scheduler.h \
|
event_data_objects.h event_scheduler.h \
|
||||||
sql_partition.h partition_info.h partition_element.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 \
|
mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
|
||||||
item.cc item_sum.cc item_buff.cc item_func.cc \
|
item.cc item_sum.cc item_buff.cc item_func.cc \
|
||||||
|
@ -581,6 +581,7 @@ struct handler_iterator {
|
|||||||
void *buffer;
|
void *buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class handler;
|
||||||
/*
|
/*
|
||||||
handlerton is a singleton structure - one instance per storage engine -
|
handlerton is a singleton structure - one instance per storage engine -
|
||||||
to provide access to storage engine functionality that works on the
|
to provide access to storage engine functionality that works on the
|
||||||
@ -1152,7 +1153,7 @@ public:
|
|||||||
virtual ~handler(void)
|
virtual ~handler(void)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(locked == FALSE);
|
DBUG_ASSERT(locked == FALSE);
|
||||||
/* TODO: DBUG_ASSERT(inited == NONE); */
|
DBUG_ASSERT(inited == NONE);
|
||||||
}
|
}
|
||||||
virtual handler *clone(MEM_ROOT *mem_root);
|
virtual handler *clone(MEM_ROOT *mem_root);
|
||||||
/** This is called after create to allow us to set up cached variables */
|
/** This is called after create to allow us to set up cached variables */
|
||||||
|
@ -1863,7 +1863,8 @@ void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row)
|
|||||||
DBUG_ASSERT(0);
|
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_always_key_or_null(JOIN_TAB *tab);
|
||||||
int join_read_next_same_or_null(READ_RECORD *info);
|
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 */
|
/* Change the access method to full table scan */
|
||||||
tab->save_read_first_record= tab->read_first_record;
|
tab->save_read_first_record= tab->read_first_record;
|
||||||
tab->save_read_record= tab->read_record.read_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.record= tab->table->record[0];
|
||||||
tab->read_record.thd= join->thd;
|
tab->read_record.thd= join->thd;
|
||||||
tab->read_record.ref_length= tab->table->file->ref_length;
|
tab->read_record.ref_length= tab->table->file->ref_length;
|
||||||
|
@ -878,6 +878,7 @@ bool general_log_write(THD *thd, enum enum_server_command command,
|
|||||||
#include "tztime.h"
|
#include "tztime.h"
|
||||||
#ifdef MYSQL_SERVER
|
#ifdef MYSQL_SERVER
|
||||||
#include "sql_servers.h"
|
#include "sql_servers.h"
|
||||||
|
#include "records.h"
|
||||||
#include "opt_range.h"
|
#include "opt_range.h"
|
||||||
|
|
||||||
#ifdef HAVE_QUERY_CACHE
|
#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);
|
int test_if_number(char *str,int *res,bool allow_wildcards);
|
||||||
void change_byte(uchar *,uint,char,char);
|
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,
|
ha_rows filesort(THD *thd, TABLE *form,struct st_sort_field *sortorder,
|
||||||
uint s_length, SQL_SELECT *select,
|
uint s_length, SQL_SELECT *select,
|
||||||
ha_rows max_rows, bool sort_positions,
|
ha_rows max_rows, bool sort_positions,
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#ifdef USE_PRAGMA_INTERFACE
|
||||||
|
#pragma implementation /* gcc class implementation */
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
@ -21,8 +24,10 @@
|
|||||||
Functions for easy reading of records, possible through a cache
|
Functions for easy reading of records, possible through a cache
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "records.h"
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
|
|
||||||
|
|
||||||
static int rr_quick(READ_RECORD *info);
|
static int rr_quick(READ_RECORD *info);
|
||||||
int rr_sequential(READ_RECORD *info);
|
int rr_sequential(READ_RECORD *info);
|
||||||
static int rr_from_tempfile(READ_RECORD *info);
|
static int rr_from_tempfile(READ_RECORD *info);
|
||||||
|
75
sql/records.h
Normal file
75
sql/records.h
Normal file
@ -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 <my_global.h> /* 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 */
|
@ -1958,15 +1958,19 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Okay, got values for all arguments. Close tables that might be used by
|
Okay, got values for all arguments. Close tables that might be used by
|
||||||
arguments evaluation. If arguments evaluation required prelocking mode,
|
arguments evaluation. If arguments evaluation required prelocking mode,
|
||||||
we'll leave it here.
|
we'll leave it here.
|
||||||
*/
|
*/
|
||||||
if (!thd->in_sub_stmt)
|
if (!thd->in_sub_stmt)
|
||||||
{
|
{
|
||||||
thd->lex->unit.cleanup();
|
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();
|
thd->rollback_item_tree_changes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2114,10 +2114,10 @@ ulong Query_cache::init_cache()
|
|||||||
file system) and so should use case insensitive collation for
|
file system) and so should use case insensitive collation for
|
||||||
comparison.
|
comparison.
|
||||||
*/
|
*/
|
||||||
VOID(hash_init(&tables,
|
VOID(my_hash_init(&tables,
|
||||||
lower_case_table_names ? &my_charset_bin :
|
lower_case_table_names ? &my_charset_bin :
|
||||||
files_charset_info,
|
files_charset_info,
|
||||||
def_table_hash_size, 0, 0,query_cache_table_get_key, 0, 0));
|
def_table_hash_size, 0, 0,query_cache_table_get_key, 0, 0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
queries_in_cache = 0;
|
queries_in_cache = 0;
|
||||||
|
@ -280,6 +280,27 @@ public:
|
|||||||
LEX_COLUMN (const String& x,const uint& y ): column (x),rights (y) {}
|
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 */
|
/* SIGNAL / RESIGNAL / GET DIAGNOSTICS */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -315,27 +336,6 @@ typedef enum enum_diag_condition_item_name
|
|||||||
*/
|
*/
|
||||||
extern const LEX_STRING Diag_condition_item_names[];
|
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 */
|
#include "sql_lex.h" /* Must be here */
|
||||||
|
|
||||||
class Delayed_insert;
|
class Delayed_insert;
|
||||||
|
@ -991,13 +991,13 @@ JOIN::optimize()
|
|||||||
}
|
}
|
||||||
if (const_tables && !thd->locked_tables &&
|
if (const_tables && !thd->locked_tables &&
|
||||||
!(select_options & SELECT_NO_UNLOCK))
|
!(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)
|
if (!conds && outer_join)
|
||||||
{
|
{
|
||||||
/* Handle the case where we have an OUTER JOIN without a WHERE */
|
/* Handle the case where we have an OUTER JOIN without a WHERE */
|
||||||
conds=new Item_int((longlong) 1,1); // Always true
|
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);
|
const_table_map, conds, 1, &error);
|
||||||
if (error)
|
if (error)
|
||||||
{ /* purecov: inspected */
|
{ /* purecov: inspected */
|
||||||
@ -2905,7 +2905,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
|
|||||||
|
|
||||||
join->join_tab=stat;
|
join->join_tab=stat;
|
||||||
join->map2table=stat_ref;
|
join->map2table=stat_ref;
|
||||||
join->table= join->all_tables=table_vector;
|
join->all_tables= table_vector;
|
||||||
join->const_tables=const_count;
|
join->const_tables=const_count;
|
||||||
join->found_const_table_map=found_const_table_map;
|
join->found_const_table_map=found_const_table_map;
|
||||||
|
|
||||||
@ -5595,7 +5595,7 @@ get_best_combination(JOIN *join)
|
|||||||
{
|
{
|
||||||
TABLE *form;
|
TABLE *form;
|
||||||
*j= *join->best_positions[tablenr].table;
|
*j= *join->best_positions[tablenr].table;
|
||||||
form=join->table[tablenr]=j->table;
|
form=join->all_tables[tablenr]=j->table;
|
||||||
used_tables|= form->map;
|
used_tables|= form->map;
|
||||||
form->reginfo.join_tab=j;
|
form->reginfo.join_tab=j;
|
||||||
if (!*j->on_expr_ref)
|
if (!*j->on_expr_ref)
|
||||||
@ -5867,7 +5867,7 @@ JOIN::make_simple_join(JOIN *parent, TABLE *tmp_table)
|
|||||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||||
|
|
||||||
join_tab= parent->join_tab_reexec;
|
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;
|
tables= 1;
|
||||||
const_tables= 0;
|
const_tables= 0;
|
||||||
const_table_map= 0;
|
const_table_map= 0;
|
||||||
@ -6899,24 +6899,23 @@ void JOIN::cleanup(bool full)
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("JOIN::cleanup");
|
DBUG_ENTER("JOIN::cleanup");
|
||||||
|
|
||||||
if (table)
|
if (all_tables)
|
||||||
{
|
{
|
||||||
JOIN_TAB *tab,*end;
|
JOIN_TAB *tab,*end;
|
||||||
/*
|
/*
|
||||||
Only a sorted table may be cached. This sorted table is always the
|
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
|
if (tables > const_tables) // Test for not-const tables
|
||||||
{
|
{
|
||||||
free_io_cache(table[const_tables]);
|
free_io_cache(all_tables[const_tables]);
|
||||||
filesort_free_buffers(table[const_tables],full);
|
filesort_free_buffers(all_tables[const_tables],full);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (full)
|
if (full)
|
||||||
{
|
{
|
||||||
for (tab= join_tab, end= tab+tables; tab != end; tab++)
|
for (tab= join_tab, end= tab+tables; tab != end; tab++)
|
||||||
tab->cleanup();
|
tab->cleanup();
|
||||||
table= 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -7245,7 +7244,7 @@ static void clear_tables(JOIN *join)
|
|||||||
are not re-calculated.
|
are not re-calculated.
|
||||||
*/
|
*/
|
||||||
for (uint i=join->const_tables ; i < join->tables ; i++)
|
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<Item> *fields,TABLE *table,Procedure *procedure)
|
|||||||
if (error == NESTED_LOOP_NO_MORE_ROWS)
|
if (error == NESTED_LOOP_NO_MORE_ROWS)
|
||||||
error= NESTED_LOOP_OK;
|
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)
|
if (table)
|
||||||
{
|
{
|
||||||
int tmp, new_errno= 0;
|
int tmp, new_errno= 0;
|
||||||
@ -11031,6 +11011,29 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
|
|||||||
if (new_errno)
|
if (new_errno)
|
||||||
table->file->print_error(new_errno,MYF(0));
|
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
|
#ifndef DBUG_OFF
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -11878,10 +11881,8 @@ join_init_quick_read_record(JOIN_TAB *tab)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int rr_sequential(READ_RECORD *info);
|
int read_first_record_seq(JOIN_TAB *tab)
|
||||||
int init_read_record_seq(JOIN_TAB *tab)
|
|
||||||
{
|
{
|
||||||
tab->read_record.read_record= rr_sequential;
|
|
||||||
if (tab->read_record.file->ha_rnd_init(1))
|
if (tab->read_record.file->ha_rnd_init(1))
|
||||||
return 1;
|
return 1;
|
||||||
return (*tab->read_record.read_record)(&tab->read_record);
|
return (*tab->read_record.read_record)(&tab->read_record);
|
||||||
|
@ -134,7 +134,6 @@ enum enum_nested_loop_state
|
|||||||
|
|
||||||
typedef enum_nested_loop_state
|
typedef enum_nested_loop_state
|
||||||
(*Next_select_func)(JOIN *, struct st_join_table *, bool);
|
(*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);
|
Next_select_func setup_end_select_func(JOIN *join);
|
||||||
|
|
||||||
|
|
||||||
@ -162,7 +161,7 @@ typedef struct st_join_table {
|
|||||||
*/
|
*/
|
||||||
uint packed_info;
|
uint packed_info;
|
||||||
|
|
||||||
Read_record_func read_first_record;
|
READ_RECORD::Setup_func read_first_record;
|
||||||
Next_select_func next_select;
|
Next_select_func next_select;
|
||||||
READ_RECORD read_record;
|
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
|
if it is executed by an alternative full table scan when the left operand of
|
||||||
the subquery predicate is evaluated to NULL.
|
the subquery predicate is evaluated to NULL.
|
||||||
*/
|
*/
|
||||||
Read_record_func save_read_first_record;/* to save read_first_record */
|
READ_RECORD::Setup_func save_read_first_record;/* to save read_first_record */
|
||||||
int (*save_read_record) (READ_RECORD *);/* to save read_record.read_record */
|
READ_RECORD::Read_func save_read_record;/* to save read_record.read_record */
|
||||||
double worst_seeks;
|
double worst_seeks;
|
||||||
key_map const_keys; /**< Keys with constant part */
|
key_map const_keys; /**< Keys with constant part */
|
||||||
key_map checked_keys; /**< Keys checked in find_best */
|
key_map checked_keys; /**< Keys checked in find_best */
|
||||||
@ -280,7 +279,7 @@ public:
|
|||||||
JOIN_TAB *join_tab,**best_ref;
|
JOIN_TAB *join_tab,**best_ref;
|
||||||
JOIN_TAB **map2table; ///< mapping between table indexes and JOIN_TABs
|
JOIN_TAB **map2table; ///< mapping between table indexes and JOIN_TABs
|
||||||
JOIN_TAB *join_tab_save; ///< saved join_tab for subquery reexecution
|
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 tables,const_tables;
|
||||||
uint send_group_parts;
|
uint send_group_parts;
|
||||||
bool sort_and_group,first_record,full_join,group, no_field_update;
|
bool sort_and_group,first_record,full_join,group, no_field_update;
|
||||||
@ -427,7 +426,7 @@ public:
|
|||||||
select_result *result_arg)
|
select_result *result_arg)
|
||||||
{
|
{
|
||||||
join_tab= join_tab_save= 0;
|
join_tab= join_tab_save= 0;
|
||||||
table= 0;
|
all_tables= 0;
|
||||||
tables= 0;
|
tables= 0;
|
||||||
const_tables= 0;
|
const_tables= 0;
|
||||||
join_list= 0;
|
join_list= 0;
|
||||||
|
@ -7477,7 +7477,7 @@ view_err:
|
|||||||
end_temporary:
|
end_temporary:
|
||||||
my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
|
my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
|
||||||
(ulong) (copied + deleted), (ulong) deleted,
|
(ulong) (copied + deleted), (ulong) deleted,
|
||||||
(ulong) thd->cuted_fields);
|
(ulong) thd->warning_info->statement_warn_count());
|
||||||
my_ok(thd, copied + deleted, 0L, tmp_name);
|
my_ok(thd, copied + deleted, 0L, tmp_name);
|
||||||
thd->some_tables_deleted=0;
|
thd->some_tables_deleted=0;
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
|
@ -833,7 +833,7 @@ int mysql_update(THD *thd,
|
|||||||
char buff[STRING_BUFFER_USUAL_SIZE];
|
char buff[STRING_BUFFER_USUAL_SIZE];
|
||||||
my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found,
|
my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found,
|
||||||
(ulong) updated,
|
(ulong) updated,
|
||||||
(ulong) thd->warning_info->statement_warn_count());
|
(ulong) thd->warning_info->statement_warn_count());
|
||||||
thd->row_count_func=
|
thd->row_count_func=
|
||||||
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
|
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
|
||||||
my_ok(thd, (ulong) thd->row_count_func, id, buff);
|
my_ok(thd, (ulong) thd->row_count_func, id, buff);
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
struct TABLE;
|
struct TABLE;
|
||||||
class Field;
|
class Field;
|
||||||
|
class THD;
|
||||||
|
|
||||||
typedef struct st_date_time_format {
|
typedef struct st_date_time_format {
|
||||||
uchar positions[8];
|
uchar positions[8];
|
||||||
@ -115,30 +116,6 @@ typedef struct st_reginfo { /* Extra info about reg */
|
|||||||
} REGINFO;
|
} 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
|
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
|
4.1 it's exported to user in the new client API. Define aliases for
|
||||||
|
@ -2892,7 +2892,7 @@ int ha_federated::info(uint flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flag & HA_STATUS_AUTO)
|
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);
|
mysql_free_result(result);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user