Merge bk-internal.mysql.com:/home/bk/mysql-5.1-community

into  zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.1-forcollapseandmerge
This commit is contained in:
cmiller@zippy.cornsilk.net 2007-11-09 14:55:32 -05:00
commit 1426320008
177 changed files with 9488 additions and 1721 deletions

View File

@ -3004,3 +3004,4 @@ win/vs71cache.txt
win/vs8cache.txt win/vs8cache.txt
zlib/*.ds? zlib/*.ds?
zlib/*.vcproj zlib/*.vcproj
libmysql_r/client_settings.h

View File

@ -36,8 +36,10 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
const unsigned char *arg, ulong arg_length, const unsigned char *arg, ulong arg_length,
my_bool skip_check, MYSQL_STMT *stmt); my_bool skip_check, MYSQL_STMT *stmt);
unsigned long cli_safe_read(MYSQL *mysql); unsigned long cli_safe_read(MYSQL *mysql);
void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode, void net_clear_error(NET *net);
const char *sqlstate); void set_stmt_errmsg(MYSQL_STMT *stmt, NET *net);
void set_stmt_error(MYSQL_STMT *stmt, int errcode, const char *sqlstate,
const char *err);
void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate); void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -686,9 +686,7 @@ int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd)
if (my_net_write(net, (uchar*) buff, SCRAMBLE_LENGTH_323 + 1) || if (my_net_write(net, (uchar*) buff, SCRAMBLE_LENGTH_323 + 1) ||
net_flush(net)) net_flush(net))
{ {
net->last_errno= CR_SERVER_LOST; set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno));
return 1; return 1;
} }
/* Read what server thinks about out new auth message report */ /* Read what server thinks about out new auth message report */
@ -701,7 +699,8 @@ int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd)
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
const char *passwd, const char *db) const char *passwd, const char *db)
{ {
char buff[512],*end=buff; char buff[USERNAME_LENGTH+SCRAMBLED_PASSWORD_CHAR_LENGTH+NAME_LEN+2];
char *end= buff;
int rc; int rc;
CHARSET_INFO *saved_cs= mysql->charset; CHARSET_INFO *saved_cs= mysql->charset;
@ -723,7 +722,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
passwd=""; passwd="";
/* Store user into the buffer */ /* Store user into the buffer */
end=strmov(end,user)+1; end= strmake(end, user, USERNAME_LENGTH) + 1;
/* write scrambled password according to server capabilities */ /* write scrambled password according to server capabilities */
if (passwd[0]) if (passwd[0])
@ -743,7 +742,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
else else
*end++= '\0'; /* empty password */ *end++= '\0'; /* empty password */
/* Add database if needed */ /* Add database if needed */
end= strmov(end, db ? db : "") + 1; end= strmake(end, db ? db : "", NAME_LEN) + 1;
/* Add character set number. */ /* Add character set number. */
@ -860,8 +859,7 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename)
/* copy filename into local memory and allocate read buffer */ /* copy filename into local memory and allocate read buffer */
if (!(buf=my_malloc(packet_length, MYF(0)))) if (!(buf=my_malloc(packet_length, MYF(0))))
{ {
strmov(net->sqlstate, unknown_sqlstate); set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY));
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@ -887,9 +885,7 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename)
{ {
DBUG_PRINT("error", DBUG_PRINT("error",
("Lost connection to MySQL server during LOAD DATA of local file")); ("Lost connection to MySQL server during LOAD DATA of local file"));
strmov(net->sqlstate, unknown_sqlstate); set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
net->last_errno=CR_SERVER_LOST;
strmov(net->last_error,ER(net->last_errno));
goto err; goto err;
} }
} }
@ -897,9 +893,7 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename)
/* Send empty packet to mark end of file */ /* Send empty packet to mark end of file */
if (my_net_write(net, (const uchar*) "", 0) || net_flush(net)) if (my_net_write(net, (const uchar*) "", 0) || net_flush(net))
{ {
strmov(net->sqlstate, unknown_sqlstate); set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
net->last_errno=CR_SERVER_LOST;
sprintf(net->last_error,ER(net->last_errno),errno);
goto err; goto err;
} }
@ -1400,9 +1394,7 @@ const char *cli_read_statistics(MYSQL *mysql)
mysql->net.read_pos[mysql->packet_length]=0; /* End of stat string */ mysql->net.read_pos[mysql->packet_length]=0; /* End of stat string */
if (!mysql->net.read_pos[0]) if (!mysql->net.read_pos[0])
{ {
strmov(mysql->net.sqlstate, unknown_sqlstate); set_mysql_error(mysql, CR_WRONG_HOST_INFO, unknown_sqlstate);
mysql->net.last_errno=CR_WRONG_HOST_INFO;
strmov(mysql->net.last_error, ER(mysql->net.last_errno));
return mysql->net.last_error; return mysql->net.last_error;
} }
return (char*) mysql->net.read_pos; return (char*) mysql->net.read_pos;
@ -1848,24 +1840,17 @@ static my_bool my_realloc_str(NET *net, ulong length)
if (buf_length + length > net->max_packet) if (buf_length + length > net->max_packet)
{ {
res= net_realloc(net, buf_length + length); res= net_realloc(net, buf_length + length);
if (res)
{
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error, ER(net->last_errno));
}
net->write_pos= net->buff+ buf_length; net->write_pos= net->buff+ buf_length;
} }
DBUG_RETURN(res); DBUG_RETURN(res);
} }
/* Clear possible error statee of struct NET */
static void net_clear_error(NET *net)
{
if (net->last_errno)
{
net->last_errno= 0;
net->last_error[0]= '\0';
strmov(net->sqlstate, not_error_sqlstate);
}
}
static void stmt_clear_error(MYSQL_STMT *stmt) static void stmt_clear_error(MYSQL_STMT *stmt)
{ {
if (stmt->last_errno) if (stmt->last_errno)
@ -1876,18 +1861,21 @@ static void stmt_clear_error(MYSQL_STMT *stmt)
} }
} }
/* /**
Set statement error code, sqlstate, and error message Set statement error code, sqlstate, and error message
from given errcode and sqlstate. from given errcode and sqlstate.
*/ */
static void set_stmt_error(MYSQL_STMT * stmt, int errcode, void set_stmt_error(MYSQL_STMT * stmt, int errcode,
const char *sqlstate) const char *sqlstate, const char *err)
{ {
DBUG_ENTER("set_stmt_error"); DBUG_ENTER("set_stmt_error");
DBUG_PRINT("enter", ("error: %d '%s'", errcode, ER(errcode))); DBUG_PRINT("enter", ("error: %d '%s'", errcode, ER(errcode)));
DBUG_ASSERT(stmt != 0); DBUG_ASSERT(stmt != 0);
if (err == 0)
err= ER(errcode);
stmt->last_errno= errcode; stmt->last_errno= errcode;
strmov(stmt->last_error, ER(errcode)); strmov(stmt->last_error, ER(errcode));
strmov(stmt->sqlstate, sqlstate); strmov(stmt->sqlstate, sqlstate);
@ -1896,21 +1884,24 @@ static void set_stmt_error(MYSQL_STMT * stmt, int errcode,
} }
/* /**
Set statement error code, sqlstate, and error message. Set statement error code, sqlstate, and error message from NET.
@param stmt a statement handle. Copy the error here.
@param net mysql->net. Source of the error.
*/ */
void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode, void set_stmt_errmsg(MYSQL_STMT *stmt, NET *net)
const char *sqlstate)
{ {
DBUG_ENTER("set_stmt_errmsg"); DBUG_ENTER("set_stmt_errmsg");
DBUG_PRINT("enter", ("error: %d/%s '%s'", errcode, sqlstate, err)); DBUG_PRINT("enter", ("error: %d/%s '%s'", net->last_errno, net->sqlstate,
net->last_error));
DBUG_ASSERT(stmt != 0); DBUG_ASSERT(stmt != 0);
stmt->last_errno= errcode; stmt->last_errno= net->last_errno;
if (err && err[0]) if (net->last_error && net->last_error[0])
strmov(stmt->last_error, err); strmov(stmt->last_error, net->last_error);
strmov(stmt->sqlstate, sqlstate); strmov(stmt->sqlstate, net->sqlstate);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -2085,7 +2076,7 @@ mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, ulong length)
if (!mysql) if (!mysql)
{ {
/* mysql can be reset in mysql_close called from mysql_reconnect */ /* mysql can be reset in mysql_close called from mysql_reconnect */
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate); set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@ -2123,23 +2114,20 @@ mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, ulong length)
stmt->state= MYSQL_STMT_INIT_DONE; stmt->state= MYSQL_STMT_INIT_DONE;
if (stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt)) if (stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt))
{ {
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno, set_stmt_errmsg(stmt, &mysql->net);
mysql->net.sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
} }
if (stmt_command(mysql, COM_STMT_PREPARE, (const uchar*) query, length, stmt)) if (stmt_command(mysql, COM_STMT_PREPARE, (const uchar*) query, length, stmt))
{ {
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno, set_stmt_errmsg(stmt, &mysql->net);
mysql->net.sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if ((*mysql->methods->read_prepare_result)(mysql, stmt)) if ((*mysql->methods->read_prepare_result)(mysql, stmt))
{ {
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno, set_stmt_errmsg(stmt, &mysql->net);
mysql->net.sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@ -2154,7 +2142,7 @@ mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, ulong length)
(stmt->param_count + (stmt->param_count +
stmt->field_count)))) stmt->field_count))))
{ {
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate); set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate, NULL);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
stmt->bind= stmt->params + stmt->param_count; stmt->bind= stmt->params + stmt->param_count;
@ -2284,7 +2272,7 @@ mysql_stmt_result_metadata(MYSQL_STMT *stmt)
if (!(result=(MYSQL_RES*) my_malloc(sizeof(*result), if (!(result=(MYSQL_RES*) my_malloc(sizeof(*result),
MYF(MY_WME | MY_ZEROFILL)))) MYF(MY_WME | MY_ZEROFILL))))
{ {
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate); set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate, NULL);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@ -2517,7 +2505,7 @@ static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param)
*/ */
if ((my_realloc_str(net, *param->length))) if ((my_realloc_str(net, *param->length)))
{ {
set_stmt_error(stmt, net->last_errno, unknown_sqlstate); set_stmt_errmsg(stmt, net);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
(*param->store_param_func)(net, param); (*param->store_param_func)(net, param);
@ -2554,7 +2542,7 @@ static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length)
stmt->insert_id= mysql->insert_id; stmt->insert_id= mysql->insert_id;
if (res) if (res)
{ {
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); set_stmt_errmsg(stmt, net);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
@ -2577,13 +2565,13 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
if (!stmt->bind_param_done) if (!stmt->bind_param_done)
{ {
set_stmt_error(stmt, CR_PARAMS_NOT_BOUND, unknown_sqlstate); set_stmt_error(stmt, CR_PARAMS_NOT_BOUND, unknown_sqlstate, NULL);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (mysql->status != MYSQL_STATUS_READY || if (mysql->status != MYSQL_STATUS_READY ||
mysql->server_status & SERVER_MORE_RESULTS_EXISTS) mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
{ {
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate, NULL);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@ -2592,7 +2580,7 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
null_count= (stmt->param_count+7) /8; null_count= (stmt->param_count+7) /8;
if (my_realloc_str(net, null_count + 1)) if (my_realloc_str(net, null_count + 1))
{ {
set_stmt_error(stmt, net->last_errno, unknown_sqlstate); set_stmt_errmsg(stmt, net);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
bzero((char*) net->write_pos, null_count); bzero((char*) net->write_pos, null_count);
@ -2605,7 +2593,7 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
{ {
if (my_realloc_str(net, 2 * stmt->param_count)) if (my_realloc_str(net, 2 * stmt->param_count))
{ {
set_stmt_error(stmt, net->last_errno, unknown_sqlstate); set_stmt_errmsg(stmt, net);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
/* /*
@ -2628,7 +2616,7 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
/* TODO: Look into avoding the following memdup */ /* TODO: Look into avoding the following memdup */
if (!(param_data= my_memdup(net->buff, length, MYF(0)))) if (!(param_data= my_memdup(net->buff, length, MYF(0))))
{ {
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate); set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate, NULL);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
result= execute(stmt, param_data, length); result= execute(stmt, param_data, length);
@ -2692,20 +2680,19 @@ static int stmt_read_row_unbuffered(MYSQL_STMT *stmt, unsigned char **row)
*/ */
if (!mysql) if (!mysql)
{ {
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate); set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
return 1; return 1;
} }
if (mysql->status != MYSQL_STATUS_GET_RESULT) if (mysql->status != MYSQL_STATUS_GET_RESULT)
{ {
set_stmt_error(stmt, stmt->unbuffered_fetch_cancelled ? set_stmt_error(stmt, stmt->unbuffered_fetch_cancelled ?
CR_FETCH_CANCELED : CR_COMMANDS_OUT_OF_SYNC, CR_FETCH_CANCELED : CR_COMMANDS_OUT_OF_SYNC,
unknown_sqlstate); unknown_sqlstate, NULL);
goto error; goto error;
} }
if ((*mysql->methods->unbuffered_fetch)(mysql, (char**) row)) if ((*mysql->methods->unbuffered_fetch)(mysql, (char**) row))
{ {
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno, set_stmt_errmsg(stmt, &mysql->net);
mysql->net.sqlstate);
/* /*
If there was an error, there are no more pending rows: If there was an error, there are no more pending rows:
reset statement status to not hang up in following reset statement status to not hang up in following
@ -2766,7 +2753,7 @@ stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row)
buff, sizeof(buff), (uchar*) 0, 0, buff, sizeof(buff), (uchar*) 0, 0,
1, NULL)) 1, NULL))
{ {
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); set_stmt_errmsg(stmt, net);
return 1; return 1;
} }
if ((*mysql->methods->read_rows_from_cursor)(stmt)) if ((*mysql->methods->read_rows_from_cursor)(stmt))
@ -2797,7 +2784,7 @@ static int
stmt_read_row_no_result_set(MYSQL_STMT *stmt __attribute__((unused)), stmt_read_row_no_result_set(MYSQL_STMT *stmt __attribute__((unused)),
unsigned char **row __attribute__((unused))) unsigned char **row __attribute__((unused)))
{ {
set_stmt_error(stmt, CR_NO_RESULT_SET, unknown_sqlstate); set_stmt_error(stmt, CR_NO_RESULT_SET, unknown_sqlstate, NULL);
return 1; return 1;
} }
@ -2847,7 +2834,7 @@ my_bool STDCALL mysql_stmt_attr_set(MYSQL_STMT *stmt,
} }
return FALSE; return FALSE;
err_not_implemented: err_not_implemented:
set_stmt_error(stmt, CR_NOT_IMPLEMENTED, unknown_sqlstate); set_stmt_error(stmt, CR_NOT_IMPLEMENTED, unknown_sqlstate, NULL);
return TRUE; return TRUE;
} }
@ -3232,7 +3219,7 @@ my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *my_bind)
{ {
if ((int) stmt->state < (int) MYSQL_STMT_PREPARE_DONE) if ((int) stmt->state < (int) MYSQL_STMT_PREPARE_DONE)
{ {
set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate); set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate, NULL);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
@ -3397,7 +3384,7 @@ mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number,
*/ */
if (param_number >= stmt->param_count) if (param_number >= stmt->param_count)
{ {
set_stmt_error(stmt, CR_INVALID_PARAMETER_NO, unknown_sqlstate); set_stmt_error(stmt, CR_INVALID_PARAMETER_NO, unknown_sqlstate, NULL);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@ -3433,8 +3420,7 @@ mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number,
buff, sizeof(buff), (uchar*) data, buff, sizeof(buff), (uchar*) data,
length, 1, NULL)) length, 1, NULL))
{ {
set_stmt_errmsg(stmt, mysql->net.last_error, set_stmt_errmsg(stmt, &mysql->net);
mysql->net.last_errno, mysql->net.sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
} }
@ -3903,7 +3889,8 @@ static void fetch_float_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
if (field->flags & ZEROFILL_FLAG && length < field->length && if (field->flags & ZEROFILL_FLAG && length < field->length &&
field->length < MAX_DOUBLE_STRING_REP_LENGTH - 1) field->length < MAX_DOUBLE_STRING_REP_LENGTH - 1)
{ {
bmove_upp((char*) buff + field->length, buff + length, length); bmove_upp((uchar*) buff + field->length, (uchar*) buff + length,
length);
bfill((char*) buff, field->length - length, '0'); bfill((char*) buff, field->length - length, '0');
length= field->length; length= field->length;
} }
@ -4502,7 +4489,7 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *my_bind)
{ {
int errorcode= (int) stmt->state < (int) MYSQL_STMT_PREPARE_DONE ? int errorcode= (int) stmt->state < (int) MYSQL_STMT_PREPARE_DONE ?
CR_NO_PREPARE_STMT : CR_NO_STMT_METADATA; CR_NO_PREPARE_STMT : CR_NO_STMT_METADATA;
set_stmt_error(stmt, errorcode, unknown_sqlstate); set_stmt_error(stmt, errorcode, unknown_sqlstate, NULL);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@ -4682,12 +4669,12 @@ int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *my_bind,
if ((int) stmt->state < (int) MYSQL_STMT_FETCH_DONE) if ((int) stmt->state < (int) MYSQL_STMT_FETCH_DONE)
{ {
set_stmt_error(stmt, CR_NO_DATA, unknown_sqlstate); set_stmt_error(stmt, CR_NO_DATA, unknown_sqlstate, NULL);
return 1; return 1;
} }
if (column >= stmt->field_count) if (column >= stmt->field_count)
{ {
set_stmt_error(stmt, CR_INVALID_PARAMETER_NO, unknown_sqlstate); set_stmt_error(stmt, CR_INVALID_PARAMETER_NO, unknown_sqlstate, NULL);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@ -4733,7 +4720,7 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
if (!mysql) if (!mysql)
{ {
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate); set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@ -4748,7 +4735,7 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc, if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc,
sizeof(MYSQL_ROWS) + pkt_len - 1))) sizeof(MYSQL_ROWS) + pkt_len - 1)))
{ {
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate); set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate, NULL);
goto err; goto err;
} }
cur->data= (MYSQL_ROW) (cur+1); cur->data= (MYSQL_ROW) (cur+1);
@ -4769,7 +4756,7 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
} }
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); set_stmt_errmsg(stmt, net);
err: err:
DBUG_RETURN(1); DBUG_RETURN(1);
@ -4836,7 +4823,7 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
if ((int) stmt->state < (int) MYSQL_STMT_EXECUTE_DONE) if ((int) stmt->state < (int) MYSQL_STMT_EXECUTE_DONE)
{ {
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate, NULL);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@ -4856,13 +4843,13 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
if (cli_advanced_command(mysql, COM_STMT_FETCH, buff, sizeof(buff), if (cli_advanced_command(mysql, COM_STMT_FETCH, buff, sizeof(buff),
(uchar*) 0, 0, 1, NULL)) (uchar*) 0, 0, 1, NULL))
{ {
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); set_stmt_errmsg(stmt, net);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
} }
else if (mysql->status != MYSQL_STATUS_GET_RESULT) else if (mysql->status != MYSQL_STATUS_GET_RESULT)
{ {
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate, NULL);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@ -5043,8 +5030,7 @@ static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags)
if ((*mysql->methods->advanced_command)(mysql, COM_STMT_RESET, buff, if ((*mysql->methods->advanced_command)(mysql, COM_STMT_RESET, buff,
sizeof(buff), 0, 0, 0, NULL)) sizeof(buff), 0, 0, 0, NULL))
{ {
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno, set_stmt_errmsg(stmt, &mysql->net);
mysql->net.sqlstate);
stmt->state= MYSQL_STMT_INIT_DONE; stmt->state= MYSQL_STMT_INIT_DONE;
return 1; return 1;
} }
@ -5117,8 +5103,7 @@ my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
int4store(buff, stmt->stmt_id); int4store(buff, stmt->stmt_id);
if ((rc= stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt))) if ((rc= stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt)))
{ {
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno, set_stmt_errmsg(stmt, &mysql->net);
mysql->net.sqlstate);
} }
} }
} }
@ -5139,7 +5124,7 @@ my_bool STDCALL mysql_stmt_reset(MYSQL_STMT *stmt)
if (!stmt->mysql) if (!stmt->mysql)
{ {
/* mysql can be reset in mysql_close called from mysql_reconnect */ /* mysql can be reset in mysql_close called from mysql_reconnect */
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate); set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
/* Reset the client and server sides of the prepared statement */ /* Reset the client and server sides of the prepared statement */
@ -5243,15 +5228,11 @@ int STDCALL mysql_next_result(MYSQL *mysql)
if (mysql->status != MYSQL_STATUS_READY) if (mysql->status != MYSQL_STATUS_READY)
{ {
strmov(mysql->net.sqlstate, unknown_sqlstate); set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
strmov(mysql->net.last_error,
ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
DBUG_RETURN(1); DBUG_RETURN(1);
} }
mysql->net.last_error[0]= 0; net_clear_error(&mysql->net);
mysql->net.last_errno= 0;
strmov(mysql->net.sqlstate, not_error_sqlstate);
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->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS)

View File

@ -81,8 +81,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
/* Check that we are calling the client functions in right order */ /* Check that we are calling the client functions in right order */
if (mysql->status != MYSQL_STATUS_READY) if (mysql->status != MYSQL_STATUS_READY)
{ {
strmov(net->last_error, set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
ER(net->last_errno=CR_COMMANDS_OUT_OF_SYNC));
return 1; return 1;
} }
@ -90,7 +89,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
thd->clear_error(); thd->clear_error();
mysql->affected_rows= ~(my_ulonglong) 0; mysql->affected_rows= ~(my_ulonglong) 0;
mysql->field_count= 0; mysql->field_count= 0;
net->last_errno= 0; net_clear_error(net);
thd->current_stmt= stmt; thd->current_stmt= stmt;
thd->store_globals(); // Fix if more than one connect thd->store_globals(); // Fix if more than one connect
@ -245,8 +244,7 @@ static my_bool emb_read_query_result(MYSQL *mysql)
mysql->fields= res->embedded_info->fields_list; mysql->fields= res->embedded_info->fields_list;
mysql->affected_rows= res->embedded_info->affected_rows; mysql->affected_rows= res->embedded_info->affected_rows;
mysql->insert_id= res->embedded_info->insert_id; mysql->insert_id= res->embedded_info->insert_id;
mysql->net.last_errno= 0; net_clear_error(&mysql->net);
mysql->net.last_error[0]= 0;
mysql->info= 0; mysql->info= 0;
if (res->embedded_info->info[0]) if (res->embedded_info->info[0])
@ -288,7 +286,7 @@ static int emb_stmt_execute(MYSQL_STMT *stmt)
if (res) if (res)
{ {
NET *net= &stmt->mysql->net; NET *net= &stmt->mysql->net;
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); set_stmt_errmsg(stmt, net);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
@ -299,14 +297,12 @@ int emb_read_binary_rows(MYSQL_STMT *stmt)
MYSQL_DATA *data; MYSQL_DATA *data;
if (!(data= emb_read_rows(stmt->mysql, 0, 0))) if (!(data= emb_read_rows(stmt->mysql, 0, 0)))
{ {
set_stmt_errmsg(stmt, stmt->mysql->net.last_error, set_stmt_errmsg(stmt, &stmt->mysql->net);
stmt->mysql->net.last_errno, stmt->mysql->net.sqlstate);
return 1; return 1;
} }
stmt->result= *data; stmt->result= *data;
my_free((char *) data, MYF(0)); my_free((char *) data, MYF(0));
set_stmt_errmsg(stmt, stmt->mysql->net.last_error, set_stmt_errmsg(stmt, &stmt->mysql->net);
stmt->mysql->net.last_errno, stmt->mysql->net.sqlstate);
return 0; return 0;
} }
@ -320,16 +316,14 @@ int emb_read_rows_from_cursor(MYSQL_STMT *stmt)
if (res->embedded_info->last_errno) if (res->embedded_info->last_errno)
{ {
embedded_get_error(mysql, res); embedded_get_error(mysql, res);
set_stmt_errmsg(stmt, mysql->net.last_error, set_stmt_errmsg(stmt, &mysql->net);
mysql->net.last_errno, mysql->net.sqlstate);
return 1; return 1;
} }
thd->cur_data= res; thd->cur_data= res;
mysql->warning_count= res->embedded_info->warning_count; mysql->warning_count= res->embedded_info->warning_count;
mysql->server_status= res->embedded_info->server_status; mysql->server_status= res->embedded_info->server_status;
mysql->net.last_errno= 0; net_clear_error(&mysql->net);
mysql->net.last_error[0]= 0;
return emb_read_binary_rows(stmt); return emb_read_binary_rows(stmt);
} }

View File

@ -1,16 +1,22 @@
############################################################# #############################################################
# Author: Chuck
#############################################################
# Purpose: To test having extra columns on the master WL#3915 # Purpose: To test having extra columns on the master WL#3915
# engine inspecific sourced part # engine inspecific sourced part
############################################################# #############################################################
# Change Author: Jeb
# Change: Cleanup and extend testing
#############################################################
# TODO: partition specific # TODO: partition specific
# -- source include/have_partition.inc # -- source include/have_partition.inc
# Note: Will be done in different test due to NDB using this
# test case.
############################################################
########### Clean up ################ ########### Clean up ################
--disable_warnings --disable_warnings
--disable_query_log --disable_query_log
DROP TABLE IF EXISTS t1,t2,t3,t4,t31; DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t10,t11,t12,t13,t14,t15,t16,t17,t18,t31;
--enable_query_log --enable_query_log
--enable_warnings --enable_warnings
@ -70,154 +76,87 @@ DROP TABLE IF EXISTS t1,t2,t3,t4,t31;
#VARCHAR(M) #VARCHAR(M)
# #
let $binformat = `SHOW VARIABLES LIKE '%binlog_format%'`;
--echo
--echo ***********************************************************
--echo ***********************************************************
--echo ***************** Start of Testing ************************
--echo ***********************************************************
--echo ***********************************************************
--echo * This test format == $binformat and engine == $engine_type
--echo ***********************************************************
--echo ***********************************************************
--echo
--echo ***** Testing more columns on the Master *****
--echo
connection master; connection master;
eval CREATE TABLE t1 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), eval CREATE TABLE t1 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20),
f5 FLOAT DEFAULT '2.00')
ENGINE=$engine_type;
sync_slave_with_master;
alter table t1 drop f5;
connection master;
INSERT into t1 values (1, 1, 1, 'first', 1.0);
sync_slave_with_master;
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 #
--query_vertical show slave status;
select * from t1 order by f3;
connection master;
DROP TABLE t1;
eval CREATE TABLE t1 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20),
f5 FLOAT DEFAULT '2.00',
f6 CHAR(4) DEFAULT 'TEST')
ENGINE=$engine_type;
sync_slave_with_master;
alter table t1 drop f5, drop f6;
connection master;
INSERT into t1 values (1, 1, 1, 'first', 1.0, 'yksi');
sync_slave_with_master;
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 #
--query_vertical show slave status;
select * from t1 order by f3;
connection master;
DROP TABLE t1;
eval CREATE TABLE t1 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20),
f5 FLOAT DEFAULT '2.00',
f6 CHAR(4) DEFAULT 'TEST',
f7 INT DEFAULT '0')
ENGINE=$engine_type;
sync_slave_with_master;
alter table t1 drop f5, drop f6, drop f7;
connection master;
INSERT into t1 values (1, 1, 1, 'first', 1.0, 'yksi', 1);
sync_slave_with_master;
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 #
--query_vertical show slave status;
select * from t1 order by f3;
connection master;
DROP TABLE t1;
eval CREATE TABLE t1 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20),
f5 FLOAT DEFAULT '2.00',
f6 CHAR(4) DEFAULT 'TEST',
f7 INT DEFAULT '0',
f8 TEXT)
ENGINE=$engine_type;
sync_slave_with_master;
alter table t1 drop f5, drop f6, drop f7, drop f8;
connection master;
INSERT into t1 values (1, 1, 1, 'first', 1.0, 'yksi', 1, 'lounge of happiness');
sync_slave_with_master;
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 #
--query_vertical show slave status;
select * from t1 order by f3;
connection master;
DROP TABLE t1;
eval CREATE TABLE t1 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20),
f5 FLOAT DEFAULT '2.00',
f6 CHAR(4) DEFAULT 'TEST',
f7 INT DEFAULT '0',
f8 TEXT,
f9 LONGBLOB)
ENGINE=$engine_type;
sync_slave_with_master;
alter table t1 drop f5, drop f6, drop f7, drop f8, drop f9;
connection master;
INSERT into t1 values (1, 1, 1, 'first', 1.0, 'yksi', 1, 'lounge of happiness', 'very fat blob');
sync_slave_with_master;
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 #
--query_vertical show slave status;
select * from t1 order by f3;
connection master;
DROP TABLE t1;
eval CREATE TABLE t1 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20),
f5 FLOAT DEFAULT '2.00',
f6 CHAR(4) DEFAULT 'TEST',
f7 INT DEFAULT '0',
f8 TEXT,
f9 LONGBLOB,
f10 BIT(63))
ENGINE=$engine_type;
sync_slave_with_master;
alter table t1 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10;
connection master;
INSERT into t1 values (1, 1, 1, 'first', 1.0, 'yksi', 1, 'lounge of happiness', 'very fat blob', b'01010101010101');
sync_slave_with_master;
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 #
--query_vertical show slave status;
select * from t1 order by f3;
connection master;
DROP TABLE t1;
eval CREATE TABLE t1 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20),
/* extra */ /* extra */
f5 FLOAT DEFAULT '2.00', f5 FLOAT DEFAULT '2.00',
f6 CHAR(4) DEFAULT 'TEST', f6 CHAR(4) DEFAULT 'TEST',
f7 INT DEFAULT '0', f7 INT DEFAULT '0',
f8 TEXT, f8 TEXT,
f9 LONGBLOB, f9 LONGBLOB,
f10 BIT(63), f10 BIT(63),
f11 VARBINARY(64)) f11 VARBINARY(64))ENGINE=$engine_type;
ENGINE=$engine_type; --echo
--echo * Alter Table on Slave and drop columns f5 through f11 *
#connection slave; --echo
sync_slave_with_master; sync_slave_with_master;
alter table t1 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11; alter table t1 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11;
--echo
--echo * Insert data in Master then update and delete some rows*
--echo
connection master; connection master;
let $j= 50;
--disable_query_log
while ($j)
{
eval INSERT INTO t1 VALUES ($j, $j, $j, 'second', 2.0, 'kaks', 2,
'got stolen from the paradise',
'very fat blob', b'01010101010101',
0x123456);
dec $j;
}
let $j= 30;
while ($j)
{
eval update t1 set f4= 'next' where f1=$j;
dec $j;
dec $j;
eval delete from t1 where f1=$j;
dec $j;
}
--enable_query_log
INSERT into t1 values (1, 1, 1, 'first', 1.0, 'yksi', 1, 'lounge of happiness', 'very fat blob', b'01010101010101', 0x123456); --echo * Select count and 20 rows from Master *
INSERT into t1 values (2, 2, 2, 'second', 2.0, 'kaks', 2, 'got stolen from the paradise', 'very fat blob', b'01010101010101', 0x123456), (3, 3, 3, 'third', 3.0, 'kolm', 3, 'got stolen from the paradise', 'very fat blob', b'01010101010101', 0x123456); --echo
update t1 set f4= 'next' where f1=1; SELECT COUNT(*) FROM t1;
delete from t1 where f1=1; --echo
SELECT f1,f2,f3,f4,f5,f6,f7,f8,f9,
select * from t1 order by f3; hex(f10),hex(f11) FROM t1 ORDER BY f3 LIMIT 20;
#connection slave; #connection slave;
sync_slave_with_master; sync_slave_with_master;
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # --echo
--query_vertical show slave status; --echo * Select count and 20 rows from Slave *
select * from t1 order by f3; --echo
SELECT COUNT(*) FROM t1;
--echo
SELECT * FROM t1 ORDER BY f3 LIMIT 20;
--echo
--echo * Show Slave Status *
--echo
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # 35 # 36 #
--query_vertical show slave status;
--echo
### Altering table def scenario ### Altering table def scenario
--echo
--echo ***** Testing Altering table def scenario *****
--echo
connection master; connection master;
@ -232,7 +171,7 @@ connection master;
f11 BINARY(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', f11 BINARY(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
f12 SET('a', 'b', 'c') default 'b') f12 SET('a', 'b', 'c') default 'b')
ENGINE=$engine_type; ENGINE=$engine_type;
--echo
eval CREATE TABLE t3 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), eval CREATE TABLE t3 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20),
/* extra */ /* extra */
f5 DOUBLE DEFAULT '2.00', f5 DOUBLE DEFAULT '2.00',
@ -243,7 +182,7 @@ connection master;
f12 SET('a', 'b', 'c') default 'b') f12 SET('a', 'b', 'c') default 'b')
ENGINE=$engine_type; ENGINE=$engine_type;
--echo
# no ENUM and SET # no ENUM and SET
eval CREATE TABLE t4 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), eval CREATE TABLE t4 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20),
/* extra */ /* extra */
@ -256,7 +195,7 @@ connection master;
f11 CHAR(255)) f11 CHAR(255))
ENGINE=$engine_type; ENGINE=$engine_type;
--echo
eval CREATE TABLE t31 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20), eval CREATE TABLE t31 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20),
/* extra */ /* extra */
@ -293,7 +232,9 @@ connection master;
f34 VARBINARY(1025), f34 VARBINARY(1025),
f35 VARCHAR(257) f35 VARCHAR(257)
) ENGINE=$engine_type; ) ENGINE=$engine_type;
--echo
--echo ** Alter tables on slave and drop columns **
--echo
#connection slave; #connection slave;
sync_slave_with_master; sync_slave_with_master;
alter table t2 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11, drop alter table t2 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11, drop
@ -308,8 +249,8 @@ f12;
drop f26, drop f27, drop f28, drop f29, drop f30, drop f31, drop f32, drop f26, drop f27, drop f28, drop f29, drop f30, drop f31, drop f32,
drop f33, drop f34, drop f35; drop f33, drop f34, drop f35;
--echo
--echo ** Insert Data into Master **
connection master; connection master;
INSERT into t2 set f1=1, f2=1, f3=1, f4='first', f8='f8: medium size blob', f10='f10: INSERT into t2 set f1=1, f2=1, f3=1, f4='first', f8='f8: medium size blob', f10='f10:
some var char'; some var char';
@ -458,7 +399,10 @@ binary data';
/*f34 VARBINARY(1025),*/ '3333 minus 3', /*f34 VARBINARY(1025),*/ '3333 minus 3',
/*f35 VARCHAR(257),*/ NULL /*f35 VARCHAR(257),*/ NULL
); );
--echo
--echo ** Sync slave with master **
--echo ** Do selects from tables **
--echo
#connection slave; #connection slave;
sync_slave_with_master; sync_slave_with_master;
@ -469,24 +413,33 @@ binary data';
select * from t31 order by f1; select * from t31 order by f1;
connection master; connection master;
--echo
--echo ** Do updates master **
--echo
update t31 set f5=555555555555555 where f3=6; update t31 set f5=555555555555555 where f3=6;
update t31 set f2=2 where f3=2; update t31 set f2=2 where f3=2;
update t31 set f1=NULL where f3=1; update t31 set f1=NULL where f3=1;
update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3;
--echo
--echo ** Delete from Master **
--echo
delete from t1; delete from t1;
delete from t2; delete from t2;
delete from t3; delete from t3;
delete from t4; delete from t4;
delete from t31; delete from t31;
--echo
--echo ** Check slave status **
--echo
#connection slave; #connection slave;
sync_slave_with_master; sync_slave_with_master;
select * from t31; select * from t31;
--replace_result $MASTER_MYPORT MASTER_PORT --replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # --replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # 35 # 36 #
--query_vertical show slave status; --query_vertical show slave status;
#### Clean Up #### #### Clean Up ####
@ -496,11 +449,600 @@ connection master;
--disable_query_log --disable_query_log
DROP TABLE t1,t2,t3,t4,t31; DROP TABLE t1,t2,t3,t4,t31;
######################################################
#connection slave; #connection slave;
sync_slave_with_master; sync_slave_with_master;
--enable_query_log --enable_query_log
--enable_warnings --enable_warnings
--echo
--echo ****************************************
--echo * columns in master at middle of table *
--echo * Expect: Proper error message *
--echo ****************************************
--echo
--echo ** Stop and Reset Slave **
--echo
STOP SLAVE;
RESET SLAVE;
--echo
--echo ** create table slave side **
eval CREATE TABLE t10 (a INT PRIMARY KEY, b BLOB, c CHAR(5)
) ENGINE=$engine_type;
# END of the tests --echo
--echo ** Connect to master and create table **
--echo
--connection master
eval CREATE TABLE t10 (a INT KEY, b BLOB, f DOUBLE DEFAULT '233',
c CHAR(5), e INT DEFAULT '1')ENGINE=$engine_type;
RESET MASTER;
--echo
--echo *** Start Slave ***
connection slave;
START SLAVE;
--echo
--echo *** Master Data Insert ***
connection master;
set @b1 = 'b1b1b1b1';
set @b1 = concat(@b1,@b1);
INSERT INTO t10 () VALUES(1,@b1,DEFAULT,'Kyle',DEFAULT),
(2,@b1,DEFAULT,'JOE',DEFAULT),
(3,@b1,DEFAULT,'QA',DEFAULT);
--echo
--echo ********************************************
--echo *** Expect slave to fail with Error 1523 ***
--echo ********************************************
--echo
connection slave;
wait_for_slave_to_stop;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
--echo
--echo *** Drop t10 ***
connection master;
DROP TABLE t10;
sync_slave_with_master;
############################################
############## Continued ###################
############################################
--echo
--echo *********************************************
--echo * More columns in master at middle of table *
--echo * Expect: Proper error message *
--echo *********************************************
--echo
--echo *** Create t11 on slave ***
STOP SLAVE;
RESET SLAVE;
eval CREATE TABLE t11 (a INT PRIMARY KEY, b BLOB, c VARCHAR(254)
) ENGINE=$engine_type;
--echo
--echo *** Create t11 on Master ***
connection master;
eval CREATE TABLE t11 (a INT KEY, b BLOB, f TEXT,
c CHAR(5) DEFAULT 'test', e INT DEFAULT '1')ENGINE=$engine_type;
RESET MASTER;
--echo
--echo *** Start Slave ***
connection slave;
START SLAVE;
--echo
--echo *** Master Data Insert ***
connection master;
set @b1 = 'b1b1b1b1';
set @b1 = concat(@b1,@b1);
INSERT INTO t11 () VALUES(1,@b1,'Testing is fun','Kyle',DEFAULT),
(2,@b1,'Testing is cool','JOE',DEFAULT),
(3,@b1,DEFAULT,'QA',DEFAULT);
--echo
--echo ********************************************
--echo *** Expect slave to fail with Error 1523 ***
--echo ********************************************
--echo
connection slave;
wait_for_slave_to_stop;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
--echo
--echo *** Drop t11 ***
connection master;
DROP TABLE t11;
sync_slave_with_master;
############################################
############## Continued ###################
############################################
--echo
--echo *********************************************
--echo * More columns in master at middle of table *
--echo * Expect: This one should pass blob-text *
--echo *********************************************
--echo
--echo *** Create t12 on slave ***
STOP SLAVE;
RESET SLAVE;
eval CREATE TABLE t12 (a INT PRIMARY KEY, b BLOB, c BLOB
) ENGINE=$engine_type;
--echo
--echo *** Create t12 on Master ***
connection master;
eval CREATE TABLE t12 (a INT KEY, b BLOB, f TEXT,
c CHAR(5) DEFAULT 'test', e INT DEFAULT '1')ENGINE=$engine_type;
RESET MASTER;
--echo
--echo *** Start Slave ***
connection slave;
START SLAVE;
--echo
--echo *** Master Data Insert ***
connection master;
set @b1 = 'b1b1b1b1';
set @b1 = concat(@b1,@b1);
INSERT INTO t12 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT),
(2,@b1,'JOE',DEFAULT,DEFAULT),
(3,@b1,'QA',DEFAULT,DEFAULT);
--echo
SELECT a,hex(b),f,c,e FROM t12 ORDER BY a;
--echo
--echo *** Select on Slave ***
sync_slave_with_master;
SELECT a,hex(b),c FROM t12 ORDER BY a;
--echo
--echo *** Drop t12 ***
connection master;
DROP TABLE t12;
sync_slave_with_master;
############################################
############## Continued ###################
############################################
--echo
--echo ****************************************************
--echo * - Alter Master adding columns at middle of table *
--echo * Expect: columns added *
--echo ****************************************************
--echo
--echo
--echo *** Create t14 on slave ***
STOP SLAVE;
RESET SLAVE;
eval CREATE TABLE t14 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5)
) ENGINE=$engine_type;
--echo
--echo *** Create t14 on Master ***
connection master;
eval CREATE TABLE t14 (c1 INT KEY, c4 BLOB, c5 CHAR(5),
c6 INT DEFAULT '1',
c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
)ENGINE=$engine_type;
RESET MASTER;
--echo
--echo *** Start Slave ***
connection slave;
START SLAVE;
--echo
--echo *** Master Data Insert ***
connection master;
ALTER TABLE t14 ADD COLUMN c2 DECIMAL(8,2) AFTER c1;
ALTER TABLE t14 ADD COLUMN c3 TEXT AFTER c2;
--echo
set @b1 = 'b1b1b1b1';
set @b1 = concat(@b1,@b1);
INSERT INTO t14 () VALUES(1,1.00,'Replication Testing Extra Col',@b1,'Kyle',DEFAULT,DEFAULT),
(2,2.00,'This Test Should work',@b1,'JOE',DEFAULT,DEFAULT),
(3,3.00,'If is does not, I will open a bug',@b1,'QA',DEFAULT,DEFAULT);
--echo
--replace_column 7 CURRENT_TIMESTAMP
SELECT c1,c2,c3,hex(c4),c5,c6,c7 FROM t14 ORDER BY c1;
--echo
--echo *** Select on Slave ****
sync_slave_with_master;
SELECT c1,c2,c3,hex(c4),c5 FROM t14 ORDER BY c1;
####################################################
--echo
--echo ****************************************************
--echo * - Alter Master Dropping columns from the middle. *
--echo * Expect: columns dropped *
--echo ****************************************************
--echo
--echo *** connect to master and drop columns ***
connection master;
ALTER TABLE t14 DROP COLUMN c2;
ALTER TABLE t14 DROP COLUMN c7;
--echo
--echo *** Select from Master ***
SELECT c1,c3,hex(c4),c5,c6 FROM t14 ORDER BY c1;
--echo
--echo ************
--echo * Bug30415 *
--echo ************
# Uncomment below once fixed
#--echo *** Select from Slave ***
#sync_slave_with_master;
#SELECT c1,c2,c3,hex(c4),c5 FROM t14 ORDER BY c1;
# Bug30415
# Remove below once fixed
#***************************
connection slave;
wait_for_slave_to_stop;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
#***************************
STOP SLAVE;
RESET SLAVE;
--echo
--echo *** Drop t14 ***
DROP TABLE t14;
connection master;
DROP TABLE t14;
RESET MASTER;
connection slave;
START SLAVE;
#################################################
--echo
--echo *************************************************
--echo * - Alter Master adding columns at end of table *
--echo * Expect: Error 1054 *
--echo *************************************************
--echo
--echo *** Create t15 on slave ***
STOP SLAVE;
RESET SLAVE;
eval CREATE TABLE t15 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5)
) ENGINE=$engine_type;
--echo
--echo *** Create t15 on Master ***
connection master;
eval CREATE TABLE t15 (c1 INT KEY, c4 BLOB, c5 CHAR(5),
c6 INT DEFAULT '1',
c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
)ENGINE=$engine_type;
RESET MASTER;
--echo
--echo *** Start Slave ***
connection slave;
START SLAVE;
--echo
--echo *** Master Data Insert ***
connection master;
ALTER TABLE t15 ADD COLUMN c2 DECIMAL(8,2) AFTER c7;
set @b1 = 'b1b1b1b1';
set @b1 = concat(@b1,@b1);
INSERT INTO t15 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT,3.00),
(2,@b1,'JOE',DEFAULT,DEFAULT,3.00),
(3,@b1,'QA',DEFAULT,DEFAULT,3.00);
--replace_column 5 CURRENT_TIMESTAMP
SELECT c1,hex(c4),c5,c6,c7,c2 FROM t15 ORDER BY c1;
--echo
--echo ********************************************
--echo *** Expect slave to fail with Error 1054 ***
--echo ********************************************
--echo
connection slave;
wait_for_slave_to_stop;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
STOP SLAVE;
RESET SLAVE;
--echo
--echo *** Drop t15 ***
DROP TABLE t15;
connection master;
DROP TABLE t15;
RESET MASTER;
connection slave;
START SLAVE;
####################################################
--echo
--echo ************************************************
--echo * - Create index on Master column not on slave *
--echo * Expect:Warning *
--echo ************************************************
--echo
--echo *** Create t16 on slave ***
STOP SLAVE;
RESET SLAVE;
eval CREATE TABLE t16 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5)
) ENGINE=$engine_type;
--echo
--echo *** Create t16 on Master ***
connection master;
eval CREATE TABLE t16 (c1 INT KEY, c4 BLOB, c5 CHAR(5),
c6 INT DEFAULT '1',
c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
)ENGINE=$engine_type;
RESET MASTER;
--echo
--echo *** Start Slave ***
connection slave;
START SLAVE;
--echo
--echo *** Master Create Index and Data Insert ***
connection master;
CREATE INDEX part_of_c6 ON t16 (c6);
set @b1 = 'b1b1b1b1';
set @b1 = concat(@b1,@b1);
INSERT INTO t16 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT),
(2,@b1,'JOE',2,DEFAULT),
(3,@b1,'QA',3,DEFAULT);
--replace_column 5 CURRENT_TIMESTAMP
SELECT c1,hex(c4),c5,c6,c7 FROM t16 ORDER BY c1;
# Uncomment the below when bug 30434 is patched
#--echo *** Select on Slave ****
#sync_slave_with_master;
#SELECT c1,hex(c4),c5 FROM t16 ORDER BY c1;
#
#--echo *** Drop t16 ***
#connection master;
#DROP TABLE t16;
#sync_slave_with_master;
# Remove the below when bug 30434 is patched
#*******************************************
--echo
--echo *****************
--echo *** BUG 30434 ***
--echo *****************
--echo
connection slave;
wait_for_slave_to_stop;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
STOP SLAVE;
RESET SLAVE;
--echo
--echo *** Drop t16 ***
DROP TABLE t16;
connection master;
DROP TABLE t16;
RESET MASTER;
connection slave;
START SLAVE;
#*******************************************
####################################################
--echo
--echo *****************************************************
--echo * - Delete rows using column on Master not on slave *
--echo * Expect: Rows Deleted *
--echo *****************************************************
--echo
--echo *** Create t17 on slave ***
STOP SLAVE;
RESET SLAVE;
eval CREATE TABLE t17 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5)
) ENGINE=$engine_type;
--echo
--echo *** Create t17 on Master ***
connection master;
eval CREATE TABLE t17 (c1 INT KEY, c4 BLOB, c5 CHAR(5),
c6 INT DEFAULT '1',
c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
)ENGINE=$engine_type;
RESET MASTER;
--echo
--echo *** Start Slave ***
connection slave;
START SLAVE;
--echo
--echo *** Master Data Insert ***
connection master;
set @b1 = 'b1b1b1b1';
set @b1 = concat(@b1,@b1);
INSERT INTO t17 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT),
(2,@b1,'JOE',2,DEFAULT),
(3,@b1,'QA',3,DEFAULT);
--replace_column 5 CURRENT_TIMESTAMP
SELECT c1,hex(c4),c5,c6,c7 FROM t17 ORDER BY c1;
--echo
--echo ** Select * from Slave **
sync_slave_with_master;
SELECT c1,hex(c4),c5 FROM t17 ORDER BY c1;
--echo
--echo ** Delete from master **
connection master;
DELETE FROM t17 WHERE c6 = 3;
--replace_column 5 CURRENT_TIMESTAMP
SELECT c1,hex(c4),c5,c6,c7 FROM t17 ORDER BY c1;
--echo
--echo ** Check slave **
sync_slave_with_master;
SELECT c1,hex(c4),c5 FROM t17 ORDER BY c1;
connection master;
DROP TABLE t17;
sync_slave_with_master;
--echo
####################################################
--echo
--echo *****************************************************
--echo * - Update row using column on Master not on slave *
--echo * Expect: Rows updated *
--echo *****************************************************
--echo
--echo ** Bug30674 **
--echo
--echo *** Create t18 on slave ***
--echo
STOP SLAVE;
RESET SLAVE;
eval CREATE TABLE t18 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5)
) ENGINE=$engine_type;
--echo
--echo *** Create t18 on Master ***
connection master;
eval CREATE TABLE t18 (c1 INT KEY, c4 BLOB, c5 CHAR(5),
c6 INT DEFAULT '1',
c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
)ENGINE=$engine_type;
RESET MASTER;
--echo
--echo *** Start Slave ***
connection slave;
START SLAVE;
--echo
--echo *** Master Data Insert ***
connection master;
set @b1 = 'b1b1b1b1';
set @b1 = concat(@b1,@b1);
INSERT INTO t18 () VALUES(1,@b1,'Kyle',DEFAULT,DEFAULT),
(2,@b1,'JOE',2,DEFAULT),
(3,@b1,'QA',3,DEFAULT);
--replace_column 5 CURRENT_TIMESTAMP
SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1;
--echo
--echo ** Select * from Slave **
sync_slave_with_master;
SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1;
--echo
--echo ** update from master **
connection master;
#######################################
# This test should be uncommented
# once bug30674 is patched
#######################################
#***************************
#UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3;
#***************************
--replace_column 5 CURRENT_TIMESTAMP
SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1;
--echo
--echo ** Check slave **
sync_slave_with_master;
SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1;
connection master;
DROP TABLE t18;
sync_slave_with_master;
--echo
####################################################
--echo
--echo *****************************************************
--echo * - Insert UUID column on Master not on slave *
--echo * Expect: Rows inserted *
--echo *****************************************************
--echo
--echo *** Create t5 on slave ***
STOP SLAVE;
RESET SLAVE;
eval CREATE TABLE t5 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5)
) ENGINE=$engine_type;
--echo
--echo *** Create t5 on Master ***
connection master;
eval CREATE TABLE t5 (c1 INT KEY, c4 BLOB, c5 CHAR(5),
c6 LONG,
c7 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
)ENGINE=$engine_type;
RESET MASTER;
--echo
--echo *** Start Slave ***
connection slave;
START SLAVE;
--echo
--echo *** Master Data Insert ***
connection master;
set @b1 = 'b1b1b1b1';
INSERT INTO t5 () VALUES(1,@b1,'Kyle',UUID(),DEFAULT),
(2,@b1,'JOE',UUID(),DEFAULT),
(3,@b1,'QA',UUID(),DEFAULT);
--replace_column 4 UUID 5 TIME
SELECT c1,hex(c4),c5,c6,c7 FROM t5 ORDER BY c1;
--echo
--echo ** Select * from Slave **
sync_slave_with_master;
SELECT c1,hex(c4),c5 FROM t5 ORDER BY c1;
connection master;
DROP TABLE t5;
sync_slave_with_master;
--echo
# END of 5.1 tests case

View File

@ -38,7 +38,7 @@ show create database mysqltest3;
connection master; connection master;
use mysqltest2; use mysqltest2;
create table t1 (a int auto_increment primary key, b varchar(100)); --eval create table t1 (a int auto_increment primary key, b varchar(100))engine=$engine_type;
set character_set_client=cp850, collation_connection=latin2_croatian_ci; set character_set_client=cp850, collation_connection=latin2_croatian_ci;
insert into t1 (b) values(@@character_set_server); insert into t1 (b) values(@@character_set_server);
insert into t1 (b) values(@@collation_server); insert into t1 (b) values(@@collation_server);
@ -146,13 +146,15 @@ set collation_server=9999998;
select "--- --3943--" as ""; select "--- --3943--" as "";
use test; use test;
CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255)); --eval CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))ENGINE=$engine_type;
SET CHARACTER_SET_CLIENT=koi8r, SET CHARACTER_SET_CLIENT=koi8r,
CHARACTER_SET_CONNECTION=cp1251, CHARACTER_SET_CONNECTION=cp1251,
CHARACTER_SET_RESULTS=koi8r; CHARACTER_SET_RESULTS=koi8r;
INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ'); INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ');
SET SQL_BIG_SELECTS=1;
select hex(c1), hex(c2) from t1; select hex(c1), hex(c2) from t1;
sync_slave_with_master; sync_slave_with_master;
SET SQL_BIG_SELECTS=1;
select hex(c1), hex(c2) from t1; select hex(c1), hex(c2) from t1;
connection master; connection master;

View File

@ -566,3 +566,35 @@ reap;
connection default; connection default;
drop table t2; drop table t2;
disconnect flush; disconnect flush;
#
# Bug#30882 Dropping a temporary table inside a stored function may cause a server crash
#
# Test HANDLER statements in conjunction with temporary tables. While the temporary table
# is open by a HANDLER, no other statement can access it.
#
--disable_warnings
drop table if exists t1;
--enable_warnings
create temporary table t1 (a int, b char(1), key a(a), key b(a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j");
select a,b from t1;
handler t1 open as a1;
handler a1 read a first;
handler a1 read a next;
handler a1 read a next;
--error ER_CANT_REOPEN_TABLE
select a,b from t1;
handler a1 read a prev;
handler a1 read a prev;
handler a1 read a=(6) where b="g";
handler a1 close;
select a,b from t1;
handler t1 open as a2;
handler a2 read a first;
handler a2 read a last;
handler a2 read a prev;
handler a2 close;
drop table t1;

View File

@ -1020,6 +1020,55 @@ SELECT * FROM t1 ORDER BY b DESC, a ASC;
DROP TABLE t1; DROP TABLE t1;
###########################################################################
--echo
--echo #
--echo # Bug#27610: ALTER TABLE ROW_FORMAT=... does not rebuild the table.
--echo #
--echo
--echo # - prepare;
--echo
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
--echo
CREATE TABLE t1(c INT)
ENGINE = InnoDB
ROW_FORMAT = COMPACT;
--echo
--echo # - initial check;
--echo
SELECT table_schema, table_name, row_format
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = DATABASE() AND table_name = 't1';
--echo
--echo # - change ROW_FORMAT and check;
--echo
ALTER TABLE t1 ROW_FORMAT = REDUNDANT;
--echo
SELECT table_schema, table_name, row_format
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = DATABASE() AND table_name = 't1';
--echo
--echo # - that's it, cleanup.
--echo
DROP TABLE t1;
###########################################################################
--echo End of 5.0 tests --echo End of 5.0 tests
# Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY # Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY

View File

@ -610,7 +610,6 @@ id ev_nm ev_cnt
6 ev_sched_1823 6 6 ev_sched_1823 6
DROP TABLE event_log; DROP TABLE event_log;
SET GLOBAL event_scheduler = OFF; SET GLOBAL event_scheduler = OFF;
DROP DATABASE events_test;
SET GLOBAL event_scheduler= ON; SET GLOBAL event_scheduler= ON;
CREATE EVENT bug28641 ON SCHEDULE AT '2038.01.18 03:00:00' CREATE EVENT bug28641 ON SCHEDULE AT '2038.01.18 03:00:00'
DO BEGIN DO BEGIN
@ -618,3 +617,105 @@ SELECT 1;
END;| END;|
SET GLOBAL event_scheduler= OFF; SET GLOBAL event_scheduler= OFF;
DROP EVENT bug28641; DROP EVENT bug28641;
#####################################################################
#
# BUG#31111: --read-only crashes MySQL (events fail to load).
#
#####################################################################
DROP USER mysqltest_u1@localhost;
DROP EVENT IF EXISTS e1;
DROP EVENT IF EXISTS e2;
GRANT EVENT ON *.* TO mysqltest_u1@localhost;
SET GLOBAL READ_ONLY = 1;
#
# Connection: u1_con (mysqltest_u1@localhost/events_test).
#
CREATE EVENT e1 ON SCHEDULE AT '2020-01-01 00:00:00' DO SET @a = 1;
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
ALTER EVENT e1 COMMENT 'comment';
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
DROP EVENT e1;
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
#
# Connection: root_con (root@localhost/events_test).
#
CREATE EVENT e1 ON SCHEDULE AT '2020-01-01 00:00:00' DO SET @a = 1;
ALTER EVENT e1 COMMENT 'comment';
DROP EVENT e1;
SET GLOBAL READ_ONLY = 0;
#
# Connection: u1_con (mysqltest_u1@localhost/test).
#
CREATE EVENT e1 ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND DO SET @a = 1;
CREATE EVENT e2 ON SCHEDULE EVERY 1 SECOND DO SET @a = 1;
SELECT
event_name,
last_executed IS NULL,
definer
FROM INFORMATION_SCHEMA.EVENTS
WHERE event_schema = 'events_test';
event_name last_executed IS NULL definer
e1 1 mysqltest_u1@localhost
e2 1 mysqltest_u1@localhost
#
# Connection: root_con (root@localhost/events_test).
#
SET GLOBAL READ_ONLY = 1;
SET GLOBAL EVENT_SCHEDULER = ON;
# Waiting for the event scheduler to execute and drop event e1...
# Waiting for the event scheduler to execute and update event e2...
SET GLOBAL EVENT_SCHEDULER = OFF;
SELECT
event_name,
last_executed IS NULL,
definer
FROM INFORMATION_SCHEMA.EVENTS
WHERE event_schema = 'events_test';
event_name last_executed IS NULL definer
e2 0 mysqltest_u1@localhost
DROP EVENT e1;
ERROR HY000: Unknown event 'e1'
# Cleanup.
DROP EVENT e2;
SET GLOBAL READ_ONLY = 0;
#
# Connection: default
#
DROP USER mysqltest_u1@localhost;
#####################################################################
#
# End of BUG#31111.
#
#####################################################################
DROP DATABASE events_test;

View File

@ -2299,8 +2299,7 @@ Handler_read_next 0
FLUSH STATUS; FLUSH STATUS;
DELETE FROM t3 WHERE (SELECT (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) x DELETE FROM t3 WHERE (SELECT (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) x
FROM t1) > 10000; FROM t1) > 10000;
Warnings: ERROR 21000: Subquery returns more than 1 row
Error 1242 Subquery returns more than 1 row
SHOW STATUS LIKE 'handler_read__e%'; SHOW STATUS LIKE 'handler_read__e%';
Variable_name Value Variable_name Value
Handler_read_key 8 Handler_read_key 8

View File

@ -575,3 +575,65 @@ ERROR 42S02: Table 'test.t1' doesn't exist
handler t1 close; handler t1 close;
handler t2 close; handler t2 close;
drop table t2; drop table t2;
drop table if exists t1;
create temporary table t1 (a int, b char(1), key a(a), key b(a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j");
select a,b from t1;
a b
0 a
1 b
2 c
3 d
4 e
5 f
6 g
7 h
8 i
9 j
handler t1 open as a1;
handler a1 read a first;
a b
0 a
handler a1 read a next;
a b
1 b
handler a1 read a next;
a b
2 c
select a,b from t1;
ERROR HY000: Can't reopen table: 'a1'
handler a1 read a prev;
a b
1 b
handler a1 read a prev;
a b
0 a
handler a1 read a=(6) where b="g";
a b
6 g
handler a1 close;
select a,b from t1;
a b
0 a
1 b
2 c
3 d
4 e
5 f
6 g
7 h
8 i
9 j
handler t1 open as a2;
handler a2 read a first;
a b
0 a
handler a2 read a last;
a b
9 j
handler a2 read a prev;
a b
8 i
handler a2 close;
drop table t1;

View File

@ -575,3 +575,65 @@ ERROR 42S02: Table 'test.t1' doesn't exist
handler t1 close; handler t1 close;
handler t2 close; handler t2 close;
drop table t2; drop table t2;
drop table if exists t1;
create temporary table t1 (a int, b char(1), key a(a), key b(a,b));
insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j");
select a,b from t1;
a b
0 a
1 b
2 c
3 d
4 e
5 f
6 g
7 h
8 i
9 j
handler t1 open as a1;
handler a1 read a first;
a b
0 a
handler a1 read a next;
a b
1 b
handler a1 read a next;
a b
2 c
select a,b from t1;
ERROR HY000: Can't reopen table: 'a1'
handler a1 read a prev;
a b
1 b
handler a1 read a prev;
a b
0 a
handler a1 read a=(6) where b="g";
a b
6 g
handler a1 close;
select a,b from t1;
a b
0 a
1 b
2 c
3 d
4 e
5 f
6 g
7 h
8 i
9 j
handler t1 open as a2;
handler a2 read a first;
a b
0 a
handler a2 read a last;
a b
9 j
handler a2 read a prev;
a b
8 i
handler a2 close;
drop table t1;

View File

@ -1287,6 +1287,40 @@ a b
2 2 2 2
3 2 3 2
1 1 1 1
DROP TABLE t1;
#
# Bug#27610: ALTER TABLE ROW_FORMAT=... does not rebuild the table.
#
# - prepare;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(c INT)
ENGINE = InnoDB
ROW_FORMAT = COMPACT;
# - initial check;
SELECT table_schema, table_name, row_format
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = DATABASE() AND table_name = 't1';
table_schema table_name row_format
test t1 Compact
# - change ROW_FORMAT and check;
ALTER TABLE t1 ROW_FORMAT = REDUNDANT;
SELECT table_schema, table_name, row_format
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = DATABASE() AND table_name = 't1';
table_schema table_name row_format
test t1 Redundant
# - that's it, cleanup.
DROP TABLE t1; DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
CREATE TABLE `t2` ( CREATE TABLE `t2` (

View File

@ -530,3 +530,32 @@ ORDER BY c.b, c.d
a b c d e f g h i j a b c d a b c d e f g h i j a b c d
2 2 1 2004-11-30 12:00:00 1 0 0 0 0 0 2 3388000 -553000 NULL 2 2 1 2004-11-30 12:00:00 1 0 0 0 0 0 2 3388000 -553000 NULL
DROP TABLE t1, t2; DROP TABLE t1, t2;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT PRIMARY KEY AUTO_INCREMENT);
INSERT INTO t1 VALUES (), (), ();
SELECT 1 AS c1
FROM t1
ORDER BY (
SELECT 1 AS c2
FROM t1
GROUP BY GREATEST(LAST_INSERT_ID(), t1.a) ASC
LIMIT 1);
c1
1
1
1
DROP TABLE t1;
CREATE TABLE t1 (a INT, b INT, INDEX (a,b));
INSERT INTO t1 (a, b)
VALUES
(1,1), (1,2), (1,3), (1,4), (1,5),
(2,2), (2,3), (2,1), (3,1), (4,1), (4,2), (4,3), (4,4), (4,5), (4,6);
EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
(SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by
SELECT 1 as RES FROM t1 AS t1_outer WHERE
(SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12;
RES
DROP TABLE t1;

View File

@ -328,4 +328,26 @@ drop table t1;
drop table t1; drop table t1;
End of 5.0 tests End of 5.0 tests
flush logs; flush logs;
BUG#31611: Security risk with BINLOG statement
SET BINLOG_FORMAT=ROW;
CREATE DATABASE mysqltest1;
CREATE USER untrusted@localhost;
GRANT SELECT ON mysqltest1.* TO untrusted@localhost;
SHOW GRANTS FOR untrusted@localhost;
Grants for untrusted@localhost
GRANT USAGE ON *.* TO 'untrusted'@'localhost'
GRANT SELECT ON `mysqltest1`.* TO 'untrusted'@'localhost'
USE mysqltest1;
CREATE TABLE t1 (a INT, b CHAR(64));
flush logs;
INSERT INTO t1 VALUES (1,USER());
flush logs;
mysqlbinlog var/log/master-bin.000017 > var/tmp/bug31611.sql
mysql mysqltest1 -uuntrusted < var/tmp/bug31611.sql
INSERT INTO t1 VALUES (1,USER());
ERROR 42000: INSERT command denied to user 'untrusted'@'localhost' for table 't1'
SELECT * FROM t1;
a b
1 root@localhost
DROP DATABASE mysqltest1;
End of 5.1 tests End of 5.1 tests

View File

@ -2680,4 +2680,21 @@ t1 CREATE TABLE `t1` (
KEY `c` (`c`(10)) KEY `c` (`c`(10))
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
drop table if exists t1, t2;
create table t1 (a int, b int);
create table t2 like t1;
insert into t1 (a, b) values (1,1), (1,2), (1,3), (1,4), (1,5),
(2,2), (2,3), (2,1), (3,1), (4,1), (4,2), (4,3), (4,4), (4,5), (4,6);
insert into t2 select a, max(b) from t1 group by a;
prepare stmt from "delete from t2 where (select (select max(b) from t1 group
by a having a < 2) x from t1) > 10000";
delete from t2 where (select (select max(b) from t1 group
by a having a < 2) x from t1) > 10000;
ERROR 21000: Subquery returns more than 1 row
execute stmt;
ERROR 21000: Subquery returns more than 1 row
execute stmt;
ERROR 21000: Subquery returns more than 1 row
deallocate prepare stmt;
drop table t1, t2;
End of 5.1 tests. End of 5.1 tests.

View File

@ -4081,6 +4081,41 @@ SELECT `x` FROM v3;
x x
1 1
DROP VIEW v1, v2, v3; DROP VIEW v1, v2, v3;
#
# Bug#30736: Row Size Too Large Error Creating a Table and
# Inserting Data.
#
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1(
c1 DECIMAL(10, 2),
c2 FLOAT);
INSERT INTO t1 VALUES (0, 1), (2, 3), (4, 5);
CREATE TABLE t2(
c3 DECIMAL(10, 2))
SELECT
c1 * c2 AS c3
FROM t1;
SELECT * FROM t1;
c1 c2
0.00 1
2.00 3
4.00 5
SELECT * FROM t2;
c3
0.00
6.00
20.00
DROP TABLE t1;
DROP TABLE t2;
End of 5.0 tests End of 5.0 tests
create table t1(a INT, KEY (a)); create table t1(a INT, KEY (a));
INSERT INTO t1 VALUES (1),(2),(3),(4),(5); INSERT INTO t1 VALUES (1),(2),(3),(4),(5);

View File

@ -1428,7 +1428,6 @@ create function bug20701() returns varchar(25) binary return "test";
ERROR 42000: This version of MySQL doesn't yet support 'return value collation' ERROR 42000: This version of MySQL doesn't yet support 'return value collation'
create function bug20701() returns varchar(25) return "test"; create function bug20701() returns varchar(25) return "test";
drop function bug20701; drop function bug20701;
End of 5.1 tests
create procedure proc_26503_error_1() create procedure proc_26503_error_1()
begin begin
retry: retry:
@ -1523,3 +1522,60 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
SELECT ..inexistent(); SELECT ..inexistent();
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.inexistent()' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.inexistent()' at line 1
USE test; USE test;
create function f1() returns int
begin
set @test = 1, password = password('foo');
return 1;
end|
ERROR HY000: Not allowed to set autocommit from a stored function or trigger
create trigger t1
before insert on t2 for each row set password = password('foo');|
ERROR HY000: Not allowed to set autocommit from a stored function or trigger
drop function if exists f1;
drop function if exists f2;
drop table if exists t1, t2;
create function f1() returns int
begin
drop temporary table t1;
return 1;
end|
create temporary table t1 as select f1();
ERROR HY000: Can't reopen table: 't1'
create function f2() returns int
begin
create temporary table t2 as select f1();
return 1;
end|
create temporary table t1 as select f2();
ERROR HY000: Can't reopen table: 't1'
drop function f1;
drop function f2;
create function f1() returns int
begin
drop temporary table t2,t1;
return 1;
end|
create function f2() returns int
begin
create temporary table t2 as select f1();
return 1;
end|
create temporary table t1 as select f2();
ERROR HY000: Can't reopen table: 't2'
drop function f1;
drop function f2;
create temporary table t2(a int);
select * from t2;
a
create function f2() returns int
begin
drop temporary table t2;
return 1;
end|
select f2();
f2()
1
drop function f2;
drop table t2;
ERROR 42S02: Unknown table 't2'
End of 5.1 tests

View File

@ -11,7 +11,7 @@ RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
CREATE AGGREGATE FUNCTION avgcost CREATE AGGREGATE FUNCTION avgcost
RETURNS REAL SONAME "UDF_EXAMPLE_LIB"; RETURNS REAL SONAME "UDF_EXAMPLE_LIB";
select myfunc_double(); select myfunc_double();
ERROR HY000: myfunc_double must have at least one argument ERROR HY000: Can't initialize function 'myfunc_double'; myfunc_double must have at least one argument
select myfunc_double(1); select myfunc_double(1);
myfunc_double(1) myfunc_double(1)
49.00 49.00
@ -24,26 +24,26 @@ select myfunc_int();
myfunc_int() myfunc_int()
0 0
select lookup(); select lookup();
ERROR HY000: Wrong arguments to lookup; Use the source ERROR HY000: Can't initialize function 'lookup'; Wrong arguments to lookup; Use the source
select lookup("127.0.0.1"); select lookup("127.0.0.1");
lookup("127.0.0.1") lookup("127.0.0.1")
127.0.0.1 127.0.0.1
select lookup(127,0,0,1); select lookup(127,0,0,1);
ERROR HY000: Wrong arguments to lookup; Use the source ERROR HY000: Can't initialize function 'lookup'; Wrong arguments to lookup; Use the source
select lookup("localhost"); select lookup("localhost");
lookup("localhost") lookup("localhost")
127.0.0.1 127.0.0.1
select reverse_lookup(); select reverse_lookup();
ERROR HY000: Wrong number of arguments to reverse_lookup; Use the source ERROR HY000: Can't initialize function 'reverse_lookup'; Wrong number of arguments to reverse_lookup; Use the source
select reverse_lookup("127.0.0.1"); select reverse_lookup("127.0.0.1");
select reverse_lookup(127,0,0,1); select reverse_lookup(127,0,0,1);
select reverse_lookup("localhost"); select reverse_lookup("localhost");
reverse_lookup("localhost") reverse_lookup("localhost")
NULL NULL
select avgcost(); select avgcost();
ERROR HY000: wrong number of arguments: AVGCOST() requires two arguments ERROR HY000: Can't initialize function 'avgcost'; wrong number of arguments: AVGCOST() requires two arguments
select avgcost(100,23.76); select avgcost(100,23.76);
ERROR HY000: wrong argument type: AVGCOST() requires an INT and a REAL ERROR HY000: Can't initialize function 'avgcost'; wrong argument type: AVGCOST() requires an INT and a REAL
create table t1(sum int, price float(24)); create table t1(sum int, price float(24));
insert into t1 values(100, 50.00), (100, 100.00); insert into t1 values(100, 50.00), (100, 100.00);
select avgcost(sum, price) from t1; select avgcost(sum, price) from t1;

View File

@ -1888,5 +1888,27 @@ set engine_condition_pushdown = 1;
SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%'); SELECT fname, lname FROM t1 WHERE (fname like 'Y%') or (lname like 'F%');
fname lname fname lname
Young Foo Young Foo
drop table t1;
create table t1 (a int, b int, c int, d int, primary key using hash(a))
engine=ndbcluster;
insert into t1 values (10,1,100,0+0x1111);
insert into t1 values (20,2,200,0+0x2222);
insert into t1 values (30,3,300,0+0x3333);
insert into t1 values (40,4,400,0+0x4444);
insert into t1 values (50,5,500,0+0x5555);
set engine_condition_pushdown = on;
select a,b,d from t1
where b in (0,1,2,5)
order by b;
a b d
10 1 4369
20 2 8738
50 5 21845
a b d
10 1 4369
20 2 8738
50 5 21845
Warnings:
Warning 4294 Scan filter is too large, discarded
set engine_condition_pushdown = @old_ecpd; set engine_condition_pushdown = @old_ecpd;
DROP TABLE t1,t2,t3,t4,t5; DROP TABLE t1,t2,t3,t4,t5;

View File

@ -0,0 +1,11 @@
drop table if exists t1;
create table t1 (a int) engine ndb;
set autocommit=1;
lock table t1 write;
set autocommit=0;
insert into t1 values (0);
rollback;
select * from t1;
a
unlock tables;
drop table t1;

View File

@ -121,3 +121,24 @@ show tables;
Tables_in_db Tables_in_db
t2 t2
drop database db; drop database db;
use test;
create table `test`.`t1$EX`
(server_id int unsigned,
master_server_id int unsigned,
master_epoch bigint unsigned,
count int unsigned,
primary key(server_id, master_server_id,
master_epoch, count))
engine ndb;
show tables like '%$%';
Tables_in_test (%$%)
t1$ex
use test;
show tables like '%$%';
Tables_in_test (%$%)
t1$ex
drop table `test`.`t1$EX`;
show tables like '%$%';
Tables_in_test (%$%)
show tables like '%$%';
Tables_in_test (%$%)

View File

@ -41,6 +41,14 @@ pk1 b c
10 0 0 10 0 0
12 2 2 12 2 2
14 1 1 14 1 1
create unique index ib on t1(b);
update t1 set c = 4 where pk1 = 12;
update ignore t1 set b = 55 where pk1 = 14;
select * from t1 order by pk1;
pk1 b c
10 0 0
12 2 4
14 55 1
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a int, b int, KEY (a, b)) ENGINE=ndbcluster; CREATE TABLE t1 (a int, b int, KEY (a, b)) ENGINE=ndbcluster;
CREATE TABLE t2 (a int, b int, UNIQUE KEY (a, b)) ENGINE=ndbcluster; CREATE TABLE t2 (a int, b int, UNIQUE KEY (a, b)) ENGINE=ndbcluster;

View File

@ -0,0 +1,75 @@
DROP TABLE IF EXISTS t1;
create table t1 (a int not null primary key, b int not null, c int,
unique index_b (b) using hash)
engine ndb;
insert into t1 values (1,10,1),(2,9,1),(3,8,1),(4,7,1),(5,6,1),(6,5,2),(7,4,2),(8,3,2),
(9,2,2),(10,1,2);
update t1 set c = 111, b = 20 where a = 1;
select * from t1 where a = 1 order by a;
a b c
1 20 111
delete from t1 where a = 1;
select * from t1 where a = 1 order by a;
a b c
update t1 set c = 12, b = 19 where b = 2;
select * from t1 where b = 2 order by a;
a b c
delete from t1 where b = 19;
select * from t1 where b = 19 order by a;
a b c
update t1 set c = 22 where a = 10 or a >= 10;
select * from t1 order by a;
a b c
2 9 1
3 8 1
4 7 1
5 6 1
6 5 2
7 4 2
8 3 2
10 1 22
update t1 set c = 23 where a in (8,10);
select * from t1 order by a;
a b c
2 9 1
3 8 1
4 7 1
5 6 1
6 5 2
7 4 2
8 3 23
10 1 23
update t1 set c = 23 where a in (7,8) or a >= 10;
select * from t1 order by a;
a b c
2 9 1
3 8 1
4 7 1
5 6 1
6 5 2
7 4 23
8 3 23
10 1 23
update t1 set c = 11 where a = 3 or b = 7;
select * from t1 where a = 3 or b = 7 order by a;
a b c
3 8 11
4 7 11
update t1 set a = 13, b = 20 where a = 3;
select * from t1 where a = 13 order by a;
a b c
13 20 11
update t1 set a = 12, b = 19 where b = 7;
select * from t1 where b = 19 order by a;
a b c
12 19 11
select * from t1 where b = 7 order by a;
a b c
update t1 set c = 12, b = 29 where a = 5 and b = 6;
select * from t1 where b = 19 order by a;
a b c
12 19 11
delete from t1 where b = 6 and c = 12;
select * from t1 where b = 6 order by a;
a b c
drop table t1;

View File

@ -9,9 +9,6 @@
# Do not use any TAB characters for whitespace. # Do not use any TAB characters for whitespace.
# #
############################################################################## ##############################################################################
ndb_dd_sql_features : Bug#29102 ndb_dd_sql_features fails in pushbuild
ndb_load : BUG#17233 2006-05-04 tomas failed load data from infile causes mysqld dbug_assert, binlog not flushed
partition_03ndb : BUG#16385 2006-03-24 mikael Partitions: crash when updating a range partitioned NDB table partition_03ndb : BUG#16385 2006-03-24 mikael Partitions: crash when updating a range partitioned NDB table
ndb_partition_error2 : HF is not sure if the test can work as internded on all the platforms ndb_partition_error2 : HF is not sure if the test can work as internded on all the platforms

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
-- source include/have_ndb.inc
# BUG 30996
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int) engine ndb;
set autocommit=1;
lock table t1 write;
set autocommit=0;
insert into t1 values (0);
rollback;
select * from t1;
unlock tables;
drop table t1;

View File

@ -122,4 +122,33 @@ connection server2;
show tables; show tables;
drop database db; drop database db;
#
# bug#31470, ndb table with special characters in name
# are not discovered correctly
connection server1; connection server1;
use test;
create table `test`.`t1$EX`
(server_id int unsigned,
master_server_id int unsigned,
master_epoch bigint unsigned,
count int unsigned,
primary key(server_id, master_server_id,
master_epoch, count))
engine ndb;
# check that table shows up ok on both servers
# before bugfix table would not show up on server2
--replace_regex /EX/ex/
show tables like '%$%';
connection server2;
use test;
--replace_regex /EX/ex/
show tables like '%$%';
# check cleanup
drop table `test`.`t1$EX`;
show tables like '%$%';
connection server1;
show tables like '%$%';

View File

@ -35,6 +35,11 @@ UPDATE IGNORE t1 set pk1 = 1, c = 2 where pk1 = 4;
select * from t1 order by pk1; select * from t1 order by pk1;
UPDATE t1 set pk1 = pk1 + 10; UPDATE t1 set pk1 = pk1 + 10;
select * from t1 order by pk1; select * from t1 order by pk1;
# bug#25817
create unique index ib on t1(b);
update t1 set c = 4 where pk1 = 12;
update ignore t1 set b = 55 where pk1 = 14;
select * from t1 order by pk1;
--disable_warnings --disable_warnings
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;

View File

@ -0,0 +1,79 @@
-- source include/have_ndb.inc
-- source include/not_embedded.inc
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
#
# New test case for WL 3686 (which is not until CGE-6.3)
# but test is committed in 5.1 to verify consistant results.
#
# When only constant expressions in update statements and
# only PK or UK in WHERE clause. No extra WHERE parts are
# allowed. WL #3687 takes of more advanced variants of
# avoiding the read before the update/delete
create table t1 (a int not null primary key, b int not null, c int,
unique index_b (b) using hash)
engine ndb;
insert into t1 values (1,10,1),(2,9,1),(3,8,1),(4,7,1),(5,6,1),(6,5,2),(7,4,2),(8,3,2),
(9,2,2),(10,1,2);
# These ones should use optimisation
update t1 set c = 111, b = 20 where a = 1;
select * from t1 where a = 1 order by a;
delete from t1 where a = 1;
select * from t1 where a = 1 order by a;
update t1 set c = 12, b = 19 where b = 2;
select * from t1 where b = 2 order by a;
delete from t1 where b = 19;
select * from t1 where b = 19 order by a;
update t1 set c = 22 where a = 10 or a >= 10;
select * from t1 order by a;
update t1 set c = 23 where a in (8,10);
select * from t1 order by a;
update t1 set c = 23 where a in (7,8) or a >= 10;
select * from t1 order by a;
# These ones should not use optimisation
update t1 set c = 11 where a = 3 or b = 7;
select * from t1 where a = 3 or b = 7 order by a;
update t1 set a = 13, b = 20 where a = 3;
select * from t1 where a = 13 order by a;
update t1 set a = 12, b = 19 where b = 7;
select * from t1 where b = 19 order by a;
select * from t1 where b = 7 order by a;
update t1 set c = 12, b = 29 where a = 5 and b = 6;
select * from t1 where b = 19 order by a;
delete from t1 where b = 6 and c = 12;
select * from t1 where b = 6 order by a;
drop table t1;

View File

@ -53,7 +53,7 @@ DELETE FROM t2 WHERE a = 2;
--echo ******************** LOAD DATA INFILE ******************** --echo ******************** LOAD DATA INFILE ********************
--exec cp ./suite/rpl/data/rpl_mixed.dat $MYSQLTEST_VARDIR/tmp/ --exec cp ./suite/rpl/data/rpl_mixed.dat $MYSQLTEST_VARDIR/tmp/
LOAD DATA INFILE '../tmp/rpl_mixed.dat' INTO TABLE t1 FIELDS TERMINATED BY '|' ; LOAD DATA INFILE '../tmp/rpl_mixed.dat' INTO TABLE t1 FIELDS TERMINATED BY '|' ;
--exec rm $MYSQLTEST_VARDIR/tmp/rpl_mixed.dat --remove_file $MYSQLTEST_VARDIR/tmp/rpl_mixed.dat
SELECT * FROM t1; SELECT * FROM t1;
--source suite/rpl/include/rpl_mixed_check_select.inc --source suite/rpl/include/rpl_mixed_check_select.inc
--source suite/rpl/include/rpl_mixed_clear_tables.inc --source suite/rpl/include/rpl_mixed_clear_tables.inc

View File

@ -40,7 +40,7 @@ show create database mysqltest3;
Database Create Database Database Create Database
mysqltest3 CREATE DATABASE `mysqltest3` /*!40100 DEFAULT CHARACTER SET armscii8 COLLATE armscii8_bin */ mysqltest3 CREATE DATABASE `mysqltest3` /*!40100 DEFAULT CHARACTER SET armscii8 COLLATE armscii8_bin */
use mysqltest2; use mysqltest2;
create table t1 (a int auto_increment primary key, b varchar(100)); create table t1 (a int auto_increment primary key, b varchar(100))engine=myisam;;
set character_set_client=cp850, collation_connection=latin2_croatian_ci; set character_set_client=cp850, collation_connection=latin2_croatian_ci;
insert into t1 (b) values(@@character_set_server); insert into t1 (b) values(@@character_set_server);
insert into t1 (b) values(@@collation_server); insert into t1 (b) values(@@collation_server);
@ -117,7 +117,7 @@ master-bin.000001 # Query # # create database mysqltest2 character set latin2
master-bin.000001 # Query # # create database mysqltest3 master-bin.000001 # Query # # create database mysqltest3
master-bin.000001 # Query # # drop database mysqltest3 master-bin.000001 # Query # # drop database mysqltest3
master-bin.000001 # Query # # create database mysqltest3 master-bin.000001 # Query # # create database mysqltest3
master-bin.000001 # Query # # use `mysqltest2`; create table t1 (a int auto_increment primary key, b varchar(100)) master-bin.000001 # Query # # use `mysqltest2`; create table t1 (a int auto_increment primary key, b varchar(100))engine=myisam
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
@ -177,14 +177,16 @@ select "--- --3943--" as "";
--- --3943-- --- --3943--
use test; use test;
CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255)); CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))ENGINE=myisam;;
SET CHARACTER_SET_CLIENT=koi8r, SET CHARACTER_SET_CLIENT=koi8r,
CHARACTER_SET_CONNECTION=cp1251, CHARACTER_SET_CONNECTION=cp1251,
CHARACTER_SET_RESULTS=koi8r; CHARACTER_SET_RESULTS=koi8r;
INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ'); INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ');
SET SQL_BIG_SELECTS=1;
select hex(c1), hex(c2) from t1; select hex(c1), hex(c2) from t1;
hex(c1) hex(c2) hex(c1) hex(c2)
CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3
SET SQL_BIG_SELECTS=1;
select hex(c1), hex(c2) from t1; select hex(c1), hex(c2) from t1;
hex(c1) hex(c2) hex(c1) hex(c2)
CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3

View File

@ -0,0 +1,215 @@
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
set timestamp=1000000000;
drop database if exists mysqltest2;
drop database if exists mysqltest3;
create database mysqltest2 character set latin2;
set @@character_set_server=latin5;
create database mysqltest3;
--- --master--
show create database mysqltest2;
Database Create Database
mysqltest2 CREATE DATABASE `mysqltest2` /*!40100 DEFAULT CHARACTER SET latin2 */
show create database mysqltest3;
Database Create Database
mysqltest3 CREATE DATABASE `mysqltest3` /*!40100 DEFAULT CHARACTER SET latin5 */
--- --slave--
show create database mysqltest2;
Database Create Database
mysqltest2 CREATE DATABASE `mysqltest2` /*!40100 DEFAULT CHARACTER SET latin2 */
show create database mysqltest3;
Database Create Database
mysqltest3 CREATE DATABASE `mysqltest3` /*!40100 DEFAULT CHARACTER SET latin5 */
set @@collation_server=armscii8_bin;
drop database mysqltest3;
create database mysqltest3;
--- --master--
show create database mysqltest3;
Database Create Database
mysqltest3 CREATE DATABASE `mysqltest3` /*!40100 DEFAULT CHARACTER SET armscii8 COLLATE armscii8_bin */
--- --slave--
show create database mysqltest3;
Database Create Database
mysqltest3 CREATE DATABASE `mysqltest3` /*!40100 DEFAULT CHARACTER SET armscii8 COLLATE armscii8_bin */
use mysqltest2;
create table t1 (a int auto_increment primary key, b varchar(100))engine=innodb;;
set character_set_client=cp850, collation_connection=latin2_croatian_ci;
insert into t1 (b) values(@@character_set_server);
insert into t1 (b) values(@@collation_server);
insert into t1 (b) values(@@character_set_client);
insert into t1 (b) values(@@character_set_connection);
insert into t1 (b) values(@@collation_connection);
--- --master--
select * from t1 order by a;
a b
1 armscii8
2 armscii8_bin
3 cp850
4 latin2
5 latin2_croatian_ci
--- --slave--
select * from mysqltest2.t1 order by a;
a b
1 armscii8
2 armscii8_bin
3 cp850
4 latin2
5 latin2_croatian_ci
select "--- --muller--" as "";
--- --muller--
set character_set_client=latin1, collation_connection=latin1_german1_ci;
truncate table t1;
insert into t1 (b) values(@@collation_connection);
insert into t1 (b) values(LEAST("Müller","Muffler"));
set collation_connection=latin1_german2_ci;
insert into t1 (b) values(@@collation_connection);
insert into t1 (b) values(LEAST("Müller","Muffler"));
--- --master--
select * from t1 order by a;
a b
1 latin1_german1_ci
2 Muffler
3 latin1_german2_ci
4 Müller
--- --slave--
select * from mysqltest2.t1 order by a;
a b
1 latin1_german1_ci
2 Muffler
3 latin1_german2_ci
4 Müller
select "--- --INSERT--" as "";
--- --INSERT--
set @a= _cp850 'Müller' collate cp850_general_ci;
truncate table t1;
insert into t1 (b) values(collation(@a));
--- --master--
select * from t1 order by a;
a b
1 cp850_general_ci
--- --slave--
select * from mysqltest2.t1 order by a;
a b
1 cp850_general_ci
drop database mysqltest2;
drop database mysqltest3;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # drop database if exists mysqltest2
master-bin.000001 # Query # # drop database if exists mysqltest3
master-bin.000001 # Query # # create database mysqltest2 character set latin2
master-bin.000001 # Query # # create database mysqltest3
master-bin.000001 # Query # # drop database mysqltest3
master-bin.000001 # Query # # create database mysqltest3
master-bin.000001 # Query # # use `mysqltest2`; create table t1 (a int auto_increment primary key, b varchar(100))engine=innodb
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `mysqltest2`; truncate table t1
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `mysqltest2`; truncate table t1
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # drop database mysqltest2
master-bin.000001 # Query # # drop database mysqltest3
select "--- --global--" as "";
--- --global--
set global character_set_server=latin2;
set global character_set_server=latin1;
set global character_set_server=latin2;
set global character_set_server=latin1;
select "--- --oneshot--" as "";
--- --oneshot--
set one_shot @@character_set_server=latin5;
set @@max_join_size=1000;
select @@character_set_server;
@@character_set_server
latin5
select @@character_set_server;
@@character_set_server
latin1
set @@character_set_server=latin5;
select @@character_set_server;
@@character_set_server
latin5
select @@character_set_server;
@@character_set_server
latin5
set one_shot max_join_size=10;
ERROR HY000: The 'SET ONE_SHOT' syntax is reserved for purposes internal to the MySQL server
set character_set_client=9999999;
ERROR 42000: Unknown character set: '9999999'
set collation_server=9999998;
ERROR HY000: Unknown collation: '9999998'
select "--- --3943--" as "";
--- --3943--
use test;
CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))ENGINE=innodb;;
SET CHARACTER_SET_CLIENT=koi8r,
CHARACTER_SET_CONNECTION=cp1251,
CHARACTER_SET_RESULTS=koi8r;
INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ');
SET SQL_BIG_SELECTS=1;
select hex(c1), hex(c2) from t1;
hex(c1) hex(c2)
CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3
SET SQL_BIG_SELECTS=1;
select hex(c1), hex(c2) from t1;
hex(c1) hex(c2)
CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3
drop table t1;
select "--- --6676--" as "";
--- --6676--
create table `t1` (
`pk` varchar(10) not null default '',
primary key (`pk`)
) engine=innodb default charset=latin1;
set @p=_latin1 'test';
update t1 set pk='test' where pk=@p;
drop table t1;

View File

@ -13,5 +13,5 @@
rpl_ddl : BUG#26418 2007-03-01 mleich Slave out of sync after CREATE/DROP TEMPORARY TABLE + ROLLBACK on master rpl_ddl : BUG#26418 2007-03-01 mleich Slave out of sync after CREATE/DROP TEMPORARY TABLE + ROLLBACK on master
rpl_invoked_features : BUG#29020 2007-06-21 Lars Non-deterministic test case rpl_invoked_features : BUG#29020 2007-06-21 Lars Non-deterministic test case
rpl_auto_increment_11932 : Bug#29809 2007-07-16 ingo Slave SQL errors in warnings file rpl_auto_increment_11932 : Bug#29809 2007-07-16 ingo Slave SQL errors in warnings file
rpl_stm_extraColmaster_ndb : WL#3915 : Statement-based replication not supported in ndb. Enable test when supported. rpl_extraColmaster_innodb : BUG#30854 : Tables name show as binary in slave err msg on vm-win2003-64-b and Solaris
rpl_row_extraColmaster_ndb : BUG#29549 : Replication of BLOBs fail for NDB rpl_extraColmaster_myisam : BUG#30854

View File

@ -12,4 +12,5 @@ set binlog_format=row;
set binlog_format=statement; set binlog_format=statement;
-- source extra/rpl_tests/rpl_extraMaster_Col.test -- source extra/rpl_tests/rpl_extraMaster_Col.test
set binlog_format=mixed;
-- source extra/rpl_tests/rpl_extraMaster_Col.test

View File

@ -11,3 +11,5 @@ set binlog_format=row;
set binlog_format=statement; set binlog_format=statement;
-- source extra/rpl_tests/rpl_extraMaster_Col.test -- source extra/rpl_tests/rpl_extraMaster_Col.test
set binlog_format=mixed;
-- source extra/rpl_tests/rpl_extraMaster_Col.test

View File

@ -0,0 +1 @@
--innodb

View File

@ -0,0 +1 @@
--innodb

View File

@ -0,0 +1,9 @@
########################################################
# By JBM 2005-02-15 Wrapped to allow reuse of test code#
# Added to skip if ndb is default #
########################################################
-- source include/not_ndb_default.inc
-- source include/have_binlog_format_row.inc
-- source include/master-slave.inc
let $engine_type=innodb;
-- source extra/rpl_tests/rpl_row_charset.test

View File

@ -1,12 +0,0 @@
###########################################
# Purpose: Wrapper for rpl_extraMaster_Col.test
# Using NDB
###########################################
-- source include/have_ndb.inc
-- source include/ndb_master-slave.inc
-- source include/have_binlog_format_row.inc
let $engine_type = 'NDB';
-- source extra/rpl_tests/rpl_extraMaster_Col.test

View File

@ -1,13 +0,0 @@
###########################################
# Purpose: Wrapper for rpl_extraMaster_Col.test
# Using NDB
###########################################
-- source include/have_ndb.inc
-- source include/ndb_master-slave.inc
-- source include/have_binlog_format_statement.inc
let $engine_type = 'NDB';
-- source extra/rpl_tests/rpl_extraMaster_Col.test

View File

@ -40,7 +40,7 @@ show create database mysqltest3;
Database Create Database Database Create Database
mysqltest3 CREATE DATABASE `mysqltest3` /*!40100 DEFAULT CHARACTER SET armscii8 COLLATE armscii8_bin */ mysqltest3 CREATE DATABASE `mysqltest3` /*!40100 DEFAULT CHARACTER SET armscii8 COLLATE armscii8_bin */
use mysqltest2; use mysqltest2;
create table t1 (a int auto_increment primary key, b varchar(100)); create table t1 (a int auto_increment primary key, b varchar(100))engine=NDB;;
set character_set_client=cp850, collation_connection=latin2_croatian_ci; set character_set_client=cp850, collation_connection=latin2_croatian_ci;
insert into t1 (b) values(@@character_set_server); insert into t1 (b) values(@@character_set_server);
insert into t1 (b) values(@@collation_server); insert into t1 (b) values(@@collation_server);
@ -117,29 +117,27 @@ master-bin.000001 # Query # # create database mysqltest2 character set latin2
master-bin.000001 # Query # # create database mysqltest3 master-bin.000001 # Query # # create database mysqltest3
master-bin.000001 # Query # # drop database mysqltest3 master-bin.000001 # Query # # drop database mysqltest3
master-bin.000001 # Query # # create database mysqltest3 master-bin.000001 # Query # # create database mysqltest3
master-bin.000001 # Query # # use `mysqltest2`; create table t1 (a int auto_increment primary key, b varchar(100)) master-bin.000001 # Query # # use `mysqltest2`; create table t1 (a int auto_increment primary key, b varchar(100))engine=NDB
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Query # # BEGIN
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Table_map # # table_id: # (mysql.ndb_apply_status)
master-bin.000001 # Write_rows # # table_id: #
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `mysqltest2`; truncate table t1 master-bin.000001 # Query # # use `mysqltest2`; truncate table t1
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Table_map # # table_id: # (mysql.ndb_apply_status)
master-bin.000001 # Write_rows # # table_id: #
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Query # # COMMIT
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # use `mysqltest2`; truncate table t1 master-bin.000001 # Query # # use `mysqltest2`; truncate table t1
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1) master-bin.000001 # Table_map # # table_id: # (mysqltest2.t1)
master-bin.000001 # Table_map # # table_id: # (mysql.ndb_apply_status)
master-bin.000001 # Write_rows # # table_id: #
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # drop database mysqltest2 master-bin.000001 # Query # # drop database mysqltest2
master-bin.000001 # Query # # drop database mysqltest3 master-bin.000001 # Query # # drop database mysqltest3
select "--- --global--" as ""; select "--- --global--" as "";
@ -177,14 +175,16 @@ select "--- --3943--" as "";
--- --3943-- --- --3943--
use test; use test;
CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255)); CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))ENGINE=NDB;;
SET CHARACTER_SET_CLIENT=koi8r, SET CHARACTER_SET_CLIENT=koi8r,
CHARACTER_SET_CONNECTION=cp1251, CHARACTER_SET_CONNECTION=cp1251,
CHARACTER_SET_RESULTS=koi8r; CHARACTER_SET_RESULTS=koi8r;
INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ'); INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ');
SET SQL_BIG_SELECTS=1;
select hex(c1), hex(c2) from t1; select hex(c1), hex(c2) from t1;
hex(c1) hex(c2) hex(c1) hex(c2)
CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3
SET SQL_BIG_SELECTS=1;
select hex(c1), hex(c2) from t1; select hex(c1), hex(c2) from t1;
hex(c1) hex(c2) hex(c1) hex(c2)
CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3

File diff suppressed because it is too large Load Diff

View File

@ -11,8 +11,8 @@
############################################################################## ##############################################################################
rpl_ndb_2innodb : BUG#19227 2006-04-20 pekka pk delete apparently not replicated rpl_ndb_2innodb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb failed on Solaris for pack_length issue
rpl_ndb_2myisam : BUG#19227 Seems to pass currently rpl_ndb_2myisam : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb failed on Solaris for pack_length issue
rpl_ndb_2other : BUG#21842 2007-08-30 tsmith test has never worked on bigendian (sol10-sparc-a, powermacg5 rpl_ndb_2other : BUG#21842 2007-08-30 tsmith test has never worked on bigendian (sol10-sparc-a, powermacg5
rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on s/AMD rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on s/AMD
rpl_ndb_innodb2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb failed on Solaris for pack_length issue rpl_ndb_innodb2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb failed on Solaris for pack_length issue
@ -20,7 +20,7 @@ rpl_ndb_myisam2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb faile
rpl_ndb_ddl : BUG#28798 2007-05-31 lars Valgrind failure in NDB rpl_ndb_ddl : BUG#28798 2007-05-31 lars Valgrind failure in NDB
rpl_ndb_mix_innodb : BUG#28123 rpl_ndb_mix_innodb.test casue slave to core on sol10-sparc-a rpl_ndb_mix_innodb : BUG#28123 rpl_ndb_mix_innodb.test casue slave to core on sol10-sparc-a
rpl_ndb_ctype_ucs2_def : BUG#27404 util thd mysql_parse sig11 when mysqld default multibyte charset rpl_ndb_ctype_ucs2_def : BUG#27404 util thd mysql_parse sig11 when mysqld default multibyte charset
rpl_ndb_extraColMaster : BUG#30854 : Tables name show as binary in slave err msg on vm-win2003-64-b and Solaris
# the below testcase have been reworked to avoid the bug, test contains comment, keep bug open # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open

View File

@ -1,8 +1,8 @@
######################################################## ########################################################
# By JBM 2005-02-15 Wrapped to allow reuse of test code# # By JBM 2005-02-15 Wrapped to allow reuse of test code#
######################################################## ########################################################
--source include/have_ndb.inc -- source include/have_ndb.inc
-- source include/have_binlog_format_row.inc -- source include/have_binlog_format_mixed_or_row.inc
-- source include/ndb_master-slave.inc -- source include/ndb_master-slave.inc
let $engine_type=NDB; let $engine_type=NDB;
-- source extra/rpl_tests/rpl_row_charset.test -- source extra/rpl_tests/rpl_row_charset.test

View File

@ -0,0 +1,14 @@
#############################################################
# Purpose: To test having extra columns on the master WL#3915
#############################################################
-- source include/have_ndb.inc
-- source include/ndb_master-slave.inc
-- source include/have_binlog_format_mixed_or_row.inc
let $engine_type = 'NDB';
set binlog_format=row;
-- source extra/rpl_tests/rpl_extraMaster_Col.test
set binlog_format=mixed;
-- source extra/rpl_tests/rpl_extraMaster_Col.test

View File

@ -454,7 +454,8 @@ create event закачка on schedule every 10 hour do select get_lock("test_l
--echo "Should have only 2 processes: the scheduler and the locked event" --echo "Should have only 2 processes: the scheduler and the locked event"
let $wait_condition= select count(*) = 2 from information_schema.processlist let $wait_condition= select count(*) = 2 from information_schema.processlist
where ( (state like 'User lock%' AND info like 'select get_lock%') where ( (state like 'User lock%' AND info like 'select get_lock%')
OR (command='Daemon' AND user='event_scheduler')); OR (command='Daemon' AND user='event_scheduler' AND
state = 'Waiting for next activation'));
--source include/wait_condition.inc --source include/wait_condition.inc
select /*2*/ user, host, db, command, state, info select /*2*/ user, host, db, command, state, info

View File

@ -712,18 +712,6 @@ DROP TABLE event_log;
#DROP DATABASE ev_db_1; #DROP DATABASE ev_db_1;
SET GLOBAL event_scheduler = OFF; SET GLOBAL event_scheduler = OFF;
#
# End of tests
#
let $wait_condition=
select count(*) = 0 from information_schema.processlist
where db='events_test' and command = 'Connect' and user=current_user();
--source include/wait_condition.inc
DROP DATABASE events_test;
# #
# Bug#28641 CREATE EVENT with '2038.01.18 03:00:00' let server crash. # Bug#28641 CREATE EVENT with '2038.01.18 03:00:00' let server crash.
# #
@ -737,3 +725,215 @@ CREATE EVENT bug28641 ON SCHEDULE AT '2038.01.18 03:00:00'
DELIMITER ;| DELIMITER ;|
SET GLOBAL event_scheduler= OFF; SET GLOBAL event_scheduler= OFF;
DROP EVENT bug28641; DROP EVENT bug28641;
###########################################################################
--echo
--echo #####################################################################
--echo #
--echo # BUG#31111: --read-only crashes MySQL (events fail to load).
--echo #
--echo #####################################################################
--echo
--error 0,ER_CANNOT_USER
DROP USER mysqltest_u1@localhost;
--disable_warnings
DROP EVENT IF EXISTS e1;
DROP EVENT IF EXISTS e2;
--enable_warnings
--echo
# Check that an ordinary user can not create/update/drop events in the
# read-only mode.
GRANT EVENT ON *.* TO mysqltest_u1@localhost;
--echo
SET GLOBAL READ_ONLY = 1;
--echo
--echo #
--echo # Connection: u1_con (mysqltest_u1@localhost/events_test).
--echo #
--connect(u1_con,localhost,mysqltest_u1,,events_test)
--echo
--error ER_OPTION_PREVENTS_STATEMENT
CREATE EVENT e1 ON SCHEDULE AT '2020-01-01 00:00:00' DO SET @a = 1;
--echo
--error ER_OPTION_PREVENTS_STATEMENT
ALTER EVENT e1 COMMENT 'comment';
--echo
--error ER_OPTION_PREVENTS_STATEMENT
DROP EVENT e1;
--echo
# Check that the super user still can create/update/drop events.
--echo #
--echo # Connection: root_con (root@localhost/events_test).
--echo #
--connect(root_con,localhost,root,,events_test)
--echo
CREATE EVENT e1 ON SCHEDULE AT '2020-01-01 00:00:00' DO SET @a = 1;
--echo
ALTER EVENT e1 COMMENT 'comment';
--echo
DROP EVENT e1;
--echo
#
# Switch to read-write mode; create test events under the user mysqltest_u1;
# switch back to read-only mode.
#
SET GLOBAL READ_ONLY = 0;
--echo
--echo #
--echo # Connection: u1_con (mysqltest_u1@localhost/test).
--echo #
--connection u1_con
--echo
CREATE EVENT e1 ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND DO SET @a = 1;
CREATE EVENT e2 ON SCHEDULE EVERY 1 SECOND DO SET @a = 1;
--echo
SELECT
event_name,
last_executed IS NULL,
definer
FROM INFORMATION_SCHEMA.EVENTS
WHERE event_schema = 'events_test';
--echo
--echo #
--echo # Connection: root_con (root@localhost/events_test).
--echo #
--connection root_con
--echo
SET GLOBAL READ_ONLY = 1;
# Check that the event scheduler is able to update event.
--echo
SET GLOBAL EVENT_SCHEDULER = ON;
--echo
--echo # Waiting for the event scheduler to execute and drop event e1...
let $wait_timeout = 2;
let $wait_condition =
SELECT COUNT(*) = 0
FROM INFORMATION_SCHEMA.EVENTS
WHERE event_schema = 'events_test' AND event_name = 'e1';
--source include/wait_condition.inc
--echo
--echo # Waiting for the event scheduler to execute and update event e2...
let $wait_condition =
SELECT last_executed IS NOT NULL
FROM INFORMATION_SCHEMA.EVENTS
WHERE event_schema = 'events_test' AND event_name = 'e2';
--source include/wait_condition.inc
--echo
SET GLOBAL EVENT_SCHEDULER = OFF;
--echo
SELECT
event_name,
last_executed IS NULL,
definer
FROM INFORMATION_SCHEMA.EVENTS
WHERE event_schema = 'events_test';
--echo
--error ER_EVENT_DOES_NOT_EXIST
DROP EVENT e1;
--echo
--echo # Cleanup.
--echo
DROP EVENT e2;
--echo
SET GLOBAL READ_ONLY = 0;
--echo
--echo #
--echo # Connection: default
--echo #
--disconnect u1_con
--disconnect root_con
--connection default
--echo
DROP USER mysqltest_u1@localhost;
--echo
--echo #####################################################################
--echo #
--echo # End of BUG#31111.
--echo #
--echo #####################################################################
--echo
###########################################################################
#
# End of tests
#
# !!! KEEP this section AT THE END of this file !!!
#
###########################################################################
let $wait_condition=
select count(*) = 0 from information_schema.processlist
where db='events_test' and command = 'Connect' and user=current_user();
--source include/wait_condition.inc
DROP DATABASE events_test;
# THIS MUST BE THE LAST LINE in this file.

View File

@ -890,6 +890,7 @@ FLUSH STATUS;
DELETE FROM t3 WHERE (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) > 10000; DELETE FROM t3 WHERE (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) > 10000;
SHOW STATUS LIKE 'handler_read__e%'; SHOW STATUS LIKE 'handler_read__e%';
FLUSH STATUS; FLUSH STATUS;
--error ER_SUBQUERY_NO_1_ROW
DELETE FROM t3 WHERE (SELECT (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) x DELETE FROM t3 WHERE (SELECT (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) x
FROM t1) > 10000; FROM t1) > 10000;
SHOW STATUS LIKE 'handler_read__e%'; SHOW STATUS LIKE 'handler_read__e%';

View File

@ -501,3 +501,43 @@ ORDER BY c.b, c.d
; ;
DROP TABLE t1, t2; DROP TABLE t1, t2;
#
# Bug #31148: bool close_thread_table(THD*, TABLE**): Assertion
# `table->key_read == 0' failed.
#
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 (a INT PRIMARY KEY AUTO_INCREMENT);
INSERT INTO t1 VALUES (), (), ();
SELECT 1 AS c1
FROM t1
ORDER BY (
SELECT 1 AS c2
FROM t1
GROUP BY GREATEST(LAST_INSERT_ID(), t1.a) ASC
LIMIT 1);
DROP TABLE t1;
#
# Bug #31974: Wrong EXPLAIN output
#
CREATE TABLE t1 (a INT, b INT, INDEX (a,b));
INSERT INTO t1 (a, b)
VALUES
(1,1), (1,2), (1,3), (1,4), (1,5),
(2,2), (2,3), (2,1), (3,1), (4,1), (4,2), (4,3), (4,4), (4,5), (4,6);
EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
(SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12;
SELECT 1 as RES FROM t1 AS t1_outer WHERE
(SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12;
DROP TABLE t1;

View File

@ -250,4 +250,31 @@ flush logs;
--exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/log/master-bin.000016 >/dev/null 2>/dev/null --exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/log/master-bin.000016 >/dev/null 2>/dev/null
--exec $MYSQL_BINLOG --force-if-open $MYSQLTEST_VARDIR/log/master-bin.000016 >/dev/null 2>/dev/null --exec $MYSQL_BINLOG --force-if-open $MYSQLTEST_VARDIR/log/master-bin.000016 >/dev/null 2>/dev/null
--echo BUG#31611: Security risk with BINLOG statement
SET BINLOG_FORMAT=ROW;
CREATE DATABASE mysqltest1;
CREATE USER untrusted@localhost;
GRANT SELECT ON mysqltest1.* TO untrusted@localhost;
SHOW GRANTS FOR untrusted@localhost;
USE mysqltest1;
CREATE TABLE t1 (a INT, b CHAR(64));
flush logs;
INSERT INTO t1 VALUES (1,USER());
flush logs;
echo mysqlbinlog var/log/master-bin.000017 > var/tmp/bug31611.sql;
exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/log/master-bin.000017 > $MYSQLTEST_VARDIR/tmp/bug31611.sql;
connect (unsecure,localhost,untrusted,,mysqltest1);
echo mysql mysqltest1 -uuntrusted < var/tmp/bug31611.sql;
error 1;
exec $MYSQL mysqltest1 -uuntrusted < $MYSQLTEST_VARDIR/tmp/bug31611.sql;
connection unsecure;
error ER_TABLEACCESS_DENIED_ERROR;
INSERT INTO t1 VALUES (1,USER());
SELECT * FROM t1;
connection default;
DROP DATABASE mysqltest1;
--echo End of 5.1 tests --echo End of 5.1 tests

View File

@ -2778,4 +2778,38 @@ execute stmt;
show create table t1; show create table t1;
drop table t1; drop table t1;
#
# Bug #32030 DELETE does not return an error and deletes rows if error
# evaluating WHERE
#
# Test that there is an error for prepared delete just like for the normal
# one.
#
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
create table t1 (a int, b int);
create table t2 like t1;
insert into t1 (a, b) values (1,1), (1,2), (1,3), (1,4), (1,5),
(2,2), (2,3), (2,1), (3,1), (4,1), (4,2), (4,3), (4,4), (4,5), (4,6);
insert into t2 select a, max(b) from t1 group by a;
prepare stmt from "delete from t2 where (select (select max(b) from t1 group
by a having a < 2) x from t1) > 10000";
--error ER_SUBQUERY_NO_1_ROW
delete from t2 where (select (select max(b) from t1 group
by a having a < 2) x from t1) > 10000;
--error ER_SUBQUERY_NO_1_ROW
execute stmt;
--error ER_SUBQUERY_NO_1_ROW
execute stmt;
deallocate prepare stmt;
drop table t1, t2;
--echo End of 5.1 tests. --echo End of 5.1 tests.

View File

@ -3473,6 +3473,54 @@ DROP VIEW v1, v2, v3;
--enable_ps_protocol --enable_ps_protocol
###########################################################################
--echo
--echo #
--echo # Bug#30736: Row Size Too Large Error Creating a Table and
--echo # Inserting Data.
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
--enable_warnings
--echo
CREATE TABLE t1(
c1 DECIMAL(10, 2),
c2 FLOAT);
--echo
INSERT INTO t1 VALUES (0, 1), (2, 3), (4, 5);
--echo
CREATE TABLE t2(
c3 DECIMAL(10, 2))
SELECT
c1 * c2 AS c3
FROM t1;
--echo
SELECT * FROM t1;
--echo
SELECT * FROM t2;
--echo
DROP TABLE t1;
DROP TABLE t2;
--echo
###########################################################################
--echo End of 5.0 tests --echo End of 5.0 tests
# #

View File

@ -2078,10 +2078,6 @@ create function bug20701() returns varchar(25) binary return "test";
create function bug20701() returns varchar(25) return "test"; create function bug20701() returns varchar(25) return "test";
drop function bug20701; drop function bug20701;
--echo End of 5.1 tests
# #
# Bug#26503 (Illegal SQL exception handler code causes the server to crash) # Bug#26503 (Illegal SQL exception handler code causes the server to crash)
# #
@ -2222,6 +2218,93 @@ SELECT .inexistent();
SELECT ..inexistent(); SELECT ..inexistent();
USE test; USE test;
#
# Bug#30904 SET PASSWORD statement is non-transactional
#
delimiter |;
--error ER_SP_CANT_SET_AUTOCOMMIT
create function f1() returns int
begin
set @test = 1, password = password('foo');
return 1;
end|
--error ER_SP_CANT_SET_AUTOCOMMIT
create trigger t1
before insert on t2 for each row set password = password('foo');|
delimiter ;|
#
# Bug#30882 Dropping a temporary table inside a stored function may cause a server crash
#
--disable_warnings
drop function if exists f1;
drop function if exists f2;
drop table if exists t1, t2;
--enable_warnings
delimiter |;
create function f1() returns int
begin
drop temporary table t1;
return 1;
end|
delimiter ;|
--error ER_CANT_REOPEN_TABLE
create temporary table t1 as select f1();
delimiter |;
create function f2() returns int
begin
create temporary table t2 as select f1();
return 1;
end|
delimiter ;|
--error ER_CANT_REOPEN_TABLE
create temporary table t1 as select f2();
drop function f1;
drop function f2;
delimiter |;
create function f1() returns int
begin
drop temporary table t2,t1;
return 1;
end|
create function f2() returns int
begin
create temporary table t2 as select f1();
return 1;
end|
delimiter ;|
--error ER_CANT_REOPEN_TABLE
create temporary table t1 as select f2();
drop function f1;
drop function f2;
create temporary table t2(a int);
select * from t2;
delimiter |;
create function f2() returns int
begin
drop temporary table t2;
return 1;
end|
delimiter ;|
select f2();
drop function f2;
--error ER_BAD_TABLE_ERROR
drop table t2;
--echo End of 5.1 tests
# #
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
# #

View File

@ -35,20 +35,20 @@ eval CREATE FUNCTION reverse_lookup
eval CREATE AGGREGATE FUNCTION avgcost eval CREATE AGGREGATE FUNCTION avgcost
RETURNS REAL SONAME "$UDF_EXAMPLE_LIB"; RETURNS REAL SONAME "$UDF_EXAMPLE_LIB";
--error 0 --error ER_CANT_INITIALIZE_UDF
select myfunc_double(); select myfunc_double();
select myfunc_double(1); select myfunc_double(1);
select myfunc_double(78654); select myfunc_double(78654);
--error 1305 --error 1305
select myfunc_nonexist(); select myfunc_nonexist();
select myfunc_int(); select myfunc_int();
--error 0 --error ER_CANT_INITIALIZE_UDF
select lookup(); select lookup();
select lookup("127.0.0.1"); select lookup("127.0.0.1");
--error 0 --error ER_CANT_INITIALIZE_UDF
select lookup(127,0,0,1); select lookup(127,0,0,1);
select lookup("localhost"); select lookup("localhost");
--error 0 --error ER_CANT_INITIALIZE_UDF
select reverse_lookup(); select reverse_lookup();
# These two functions should return "localhost", but it's # These two functions should return "localhost", but it's
@ -59,9 +59,9 @@ select reverse_lookup(127,0,0,1);
--enable_result_log --enable_result_log
select reverse_lookup("localhost"); select reverse_lookup("localhost");
--error 0 --error ER_CANT_INITIALIZE_UDF
select avgcost(); select avgcost();
--error 0 --error ER_CANT_INITIALIZE_UDF
select avgcost(100,23.76); select avgcost(100,23.76);
create table t1(sum int, price float(24)); create table t1(sum int, price float(24));
insert into t1 values(100, 50.00), (100, 100.00); insert into t1 values(100, 50.00), (100, 100.00);

View File

@ -79,6 +79,9 @@ int main(int argc, char *argv[])
{ {
int return_value; int return_value;
puts("\n"
"WARNING: This program is deprecated and will be removed in 6.0.\n");
/* Initialize. */ /* Initialize. */
MY_INIT(argv[0]); MY_INIT(argv[0]);

View File

@ -272,6 +272,76 @@ static int wait_for_data(my_socket fd, uint timeout)
} }
#endif /* defined(__WIN__) || defined(__NETWARE__) */ #endif /* defined(__WIN__) || defined(__NETWARE__) */
/**
Set the internal error message to mysql handler
@param mysql connection handle (client side)
@param errcode CR_ error code, passed to ER macro to get
error text
@parma sqlstate SQL standard sqlstate
*/
void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate)
{
NET *net;
DBUG_ENTER("set_mysql_error");
DBUG_PRINT("enter", ("error :%d '%s'", errcode, ER(errcode)));
DBUG_ASSERT(mysql != 0);
net= &mysql->net;
net->last_errno= errcode;
strmov(net->last_error, ER(errcode));
strmov(net->sqlstate, sqlstate);
DBUG_VOID_RETURN;
}
/**
Clear possible error state of struct NET
@param net clear the state of the argument
*/
void net_clear_error(NET *net)
{
net->last_errno= 0;
net->last_error[0]= '\0';
strmov(net->sqlstate, not_error_sqlstate);
}
/**
Set an error message on the client.
@param mysql connection handle
@param errcode CR_* errcode, for client errors
@param sqlstate SQL standard sql state, unknown_sqlstate for the
majority of client errors.
@param format error message template, in sprintf format
@param ... variable number of arguments
*/
static void set_mysql_extended_error(MYSQL *mysql, int errcode,
const char *sqlstate,
const char *format, ...)
{
NET *net;
va_list args;
DBUG_ENTER("set_mysql_extended_error");
DBUG_PRINT("enter", ("error :%d '%s'", errcode, format));
DBUG_ASSERT(mysql != 0);
net= &mysql->net;
net->last_errno= errcode;
va_start(args, format);
my_vsnprintf(net->last_error, sizeof(net->last_error)-1,
format, args);
va_end(args);
strmov(net->sqlstate, sqlstate);
DBUG_VOID_RETURN;
}
/* /*
Create a named pipe connection Create a named pipe connection
@ -279,7 +349,7 @@ static int wait_for_data(my_socket fd, uint timeout)
#ifdef __WIN__ #ifdef __WIN__
HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host, HANDLE create_named_pipe(MYSQL *mysql, uint connect_timeout, char **arg_host,
char **arg_unix_socket) char **arg_unix_socket)
{ {
HANDLE hPipe=INVALID_HANDLE_VALUE; HANDLE hPipe=INVALID_HANDLE_VALUE;
@ -312,42 +382,34 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
break; break;
if (GetLastError() != ERROR_PIPE_BUSY) if (GetLastError() != ERROR_PIPE_BUSY)
{ {
net->last_errno=CR_NAMEDPIPEOPEN_ERROR; set_mysql_extended_error(mysql, CR_NAMEDPIPEOPEN_ERROR,
strmov(net->sqlstate, unknown_sqlstate); unknown_sqlstate, ER(CR_NAMEDPIPEOPEN_ERROR),
my_snprintf(net->last_error, sizeof(net->last_error)-1, host, unix_socket, (ulong) GetLastError());
ER(net->last_errno), host, unix_socket,
(ulong) GetLastError());
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
/* wait for for an other instance */ /* wait for for an other instance */
if (! WaitNamedPipe(pipe_name, connect_timeout*1000) ) if (! WaitNamedPipe(pipe_name, connect_timeout*1000) )
{ {
net->last_errno=CR_NAMEDPIPEWAIT_ERROR; set_mysql_extended_error(mysql, CR_NAMEDPIPEWAIT_ERROR, unknown_sqlstate,
strmov(net->sqlstate, unknown_sqlstate); ER(CR_NAMEDPIPEWAIT_ERROR),
my_snprintf(net->last_error, sizeof(net->last_error)-1, host, unix_socket, (ulong) GetLastError());
ER(net->last_errno), host, unix_socket,
(ulong) GetLastError());
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
} }
if (hPipe == INVALID_HANDLE_VALUE) if (hPipe == INVALID_HANDLE_VALUE)
{ {
net->last_errno=CR_NAMEDPIPEOPEN_ERROR; set_mysql_extended_error(mysql, CR_NAMEDPIPEOPEN_ERROR, unknown_sqlstate,
strmov(net->sqlstate, unknown_sqlstate); ER(CR_NAMEDPIPEOPEN_ERROR), host, unix_socket,
my_snprintf(net->last_error, sizeof(net->last_error)-1, (ulong) GetLastError());
ER(net->last_errno), host, unix_socket,
(ulong) GetLastError());
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
dwMode = PIPE_READMODE_BYTE | PIPE_WAIT; dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
if ( !SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL) ) if ( !SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL) )
{ {
CloseHandle( hPipe ); CloseHandle( hPipe );
net->last_errno=CR_NAMEDPIPESETSTATE_ERROR; set_mysql_extended_error(mysql, CR_NAMEDPIPESETSTATE_ERROR,
strmov(net->sqlstate, unknown_sqlstate); unknown_sqlstate, ER(CR_NAMEDPIPESETSTATE_ERROR),
my_snprintf(net->last_error, sizeof(net->last_error)-1, host, unix_socket, (ulong) GetLastError());
ER(net->last_errno),host, unix_socket,
(ulong) GetLastError());
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
*arg_host=host ; *arg_unix_socket=unix_socket; /* connect arg */ *arg_host=host ; *arg_unix_socket=unix_socket; /* connect arg */
@ -566,14 +628,12 @@ err:
CloseHandle(handle_connect_file_map); CloseHandle(handle_connect_file_map);
if (error_allow) if (error_allow)
{ {
net->last_errno=error_allow;
strmov(net->sqlstate, unknown_sqlstate);
if (error_allow == CR_SHARED_MEMORY_EVENT_ERROR) if (error_allow == CR_SHARED_MEMORY_EVENT_ERROR)
my_snprintf(net->last_error,sizeof(net->last_error)-1, set_mysql_extended_error(mysql, error_allow, unknown_sqlstate,
ER(net->last_errno),suffix_pos,error_code); ER(error_allow), suffix_pos, error_code);
else else
my_snprintf(net->last_error,sizeof(net->last_error)-1, set_mysql_extended_error(mysql, error_allow, unknown_sqlstate,
ER(net->last_errno),error_code); ER(error_allow), error_code);
return(INVALID_HANDLE_VALUE); return(INVALID_HANDLE_VALUE);
} }
return(handle_map); return(handle_map);
@ -683,10 +743,8 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
DBUG_RETURN(1); DBUG_RETURN(1);
} }
net->last_error[0]=0; net_clear_error(net);
net->last_errno= 0; net->report_error=0;
strmov(net->sqlstate, not_error_sqlstate);
mysql->net.report_error=0;
mysql->info=0; mysql->info=0;
mysql->affected_rows= ~(my_ulonglong) 0; mysql->affected_rows= ~(my_ulonglong) 0;
/* /*
@ -703,8 +761,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
socket_errno)); socket_errno));
if (net->last_errno == ER_NET_PACKET_TOO_LARGE) if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
{ {
net->last_errno=CR_NET_PACKET_TOO_LARGE; set_mysql_error(mysql, CR_NET_PACKET_TOO_LARGE, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno));
goto end; goto end;
} }
end_server(mysql); end_server(mysql);
@ -713,8 +770,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
if (net_write_command(net,(uchar) command, header, header_length, if (net_write_command(net,(uchar) command, header, header_length,
arg, arg_length)) arg, arg_length))
{ {
net->last_errno=CR_SERVER_GONE_ERROR; set_mysql_error(mysql, CR_SERVER_GONE_ERROR, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno));
goto end; goto end;
} }
} }
@ -741,48 +797,6 @@ void free_old_query(MYSQL *mysql)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/*
Set the internal error message to mysql handler
*/
void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate)
{
NET *net;
DBUG_ENTER("set_mysql_error");
DBUG_PRINT("enter", ("error :%d '%s'", errcode, ER(errcode)));
DBUG_ASSERT(mysql != 0);
net= &mysql->net;
net->last_errno= errcode;
strmov(net->last_error, ER(errcode));
strmov(net->sqlstate, sqlstate);
DBUG_VOID_RETURN;
}
static void set_mysql_extended_error(MYSQL *mysql, int errcode,
const char *sqlstate,
const char *format, ...)
{
NET *net;
va_list args;
DBUG_ENTER("set_mysql_extended_error");
DBUG_PRINT("enter", ("error :%d '%s'", errcode, format));
DBUG_ASSERT(mysql != 0);
net= &mysql->net;
net->last_errno= errcode;
va_start(args, format);
my_vsnprintf(net->last_error, sizeof(net->last_error)-1,
format, args);
va_end(args);
strmov(net->sqlstate, sqlstate);
DBUG_VOID_RETURN;
}
/* /*
Flush result set sent from server Flush result set sent from server
*/ */
@ -846,9 +860,8 @@ static int check_license(MYSQL *mysql)
{ {
if (net->last_errno == ER_UNKNOWN_SYSTEM_VARIABLE) if (net->last_errno == ER_UNKNOWN_SYSTEM_VARIABLE)
{ {
net->last_errno= CR_WRONG_LICENSE; set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate,
my_snprintf(net->last_error, sizeof(net->last_error)-1, ER(CR_WRONG_LICENSE), required_license);
ER(net->last_errno), required_license);
} }
return 1; return 1;
} }
@ -864,9 +877,8 @@ static int check_license(MYSQL *mysql)
(!row || !row[0] || (!row || !row[0] ||
strncmp(row[0], required_license, sizeof(required_license)))) strncmp(row[0], required_license, sizeof(required_license))))
{ {
net->last_errno= CR_WRONG_LICENSE; set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate,
my_snprintf(net->last_error, sizeof(net->last_error)-1, ER(CR_WRONG_LICENSE), required_license);
ER(net->last_errno), required_license);
} }
mysql_free_result(res); mysql_free_result(res);
return net->last_errno; return net->last_errno;
@ -1717,7 +1729,6 @@ static MYSQL_METHODS client_methods=
C_MODE_START C_MODE_START
int mysql_init_character_set(MYSQL *mysql) int mysql_init_character_set(MYSQL *mysql)
{ {
NET *net= &mysql->net;
const char *default_collation_name; const char *default_collation_name;
/* Set character set */ /* Set character set */
@ -1761,24 +1772,22 @@ int mysql_init_character_set(MYSQL *mysql)
} }
charsets_dir= save; charsets_dir= save;
} }
if (!mysql->charset) if (!mysql->charset)
{ {
net->last_errno=CR_CANT_READ_CHARSET;
strmov(net->sqlstate, unknown_sqlstate);
if (mysql->options.charset_dir) if (mysql->options.charset_dir)
my_snprintf(net->last_error, sizeof(net->last_error)-1, set_mysql_extended_error(mysql, CR_CANT_READ_CHARSET, unknown_sqlstate,
ER(net->last_errno), ER(CR_CANT_READ_CHARSET),
mysql->options.charset_name, mysql->options.charset_name,
mysql->options.charset_dir); mysql->options.charset_dir);
else else
{ {
char cs_dir_name[FN_REFLEN]; char cs_dir_name[FN_REFLEN];
get_charsets_dir(cs_dir_name); get_charsets_dir(cs_dir_name);
my_snprintf(net->last_error, sizeof(net->last_error)-1, set_mysql_extended_error(mysql, CR_CANT_READ_CHARSET, unknown_sqlstate,
ER(net->last_errno), ER(CR_CANT_READ_CHARSET),
mysql->options.charset_name, mysql->options.charset_name,
cs_dir_name); cs_dir_name);
} }
return 1; return 1;
} }
@ -1910,10 +1919,10 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
DBUG_PRINT("info",("Using UNIX sock '%s'",unix_socket)); DBUG_PRINT("info",("Using UNIX sock '%s'",unix_socket));
if ((sock = socket(AF_UNIX,SOCK_STREAM,0)) == SOCKET_ERROR) if ((sock = socket(AF_UNIX,SOCK_STREAM,0)) == SOCKET_ERROR)
{ {
net->last_errno=CR_SOCKET_CREATE_ERROR; set_mysql_extended_error(mysql, CR_SOCKET_CREATE_ERROR,
strmov(net->sqlstate, unknown_sqlstate); unknown_sqlstate,
my_snprintf(net->last_error,sizeof(net->last_error)-1, ER(CR_SOCKET_CREATE_ERROR),
ER(net->last_errno),socket_errno); socket_errno);
goto error; goto error;
} }
net->vio= vio_new(sock, VIO_TYPE_SOCKET, net->vio= vio_new(sock, VIO_TYPE_SOCKET,
@ -1926,10 +1935,10 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
{ {
DBUG_PRINT("error",("Got error %d on connect to local server", DBUG_PRINT("error",("Got error %d on connect to local server",
socket_errno)); socket_errno));
net->last_errno=CR_CONNECTION_ERROR; set_mysql_extended_error(mysql, CR_CONNECTION_ERROR,
strmov(net->sqlstate, unknown_sqlstate); unknown_sqlstate,
my_snprintf(net->last_error,sizeof(net->last_error)-1, ER(CR_CONNECTION_ERROR),
ER(net->last_errno),unix_socket,socket_errno); unix_socket, socket_errno);
goto error; goto error;
} }
mysql->options.protocol=MYSQL_PROTOCOL_SOCKET; mysql->options.protocol=MYSQL_PROTOCOL_SOCKET;
@ -1941,8 +1950,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
(! have_tcpip && (unix_socket || !host && is_NT())))) (! have_tcpip && (unix_socket || !host && is_NT()))))
{ {
sock=0; sock=0;
if ((hPipe=create_named_pipe(net, mysql->options.connect_timeout, if ((hPipe= create_named_pipe(mysql, mysql->options.connect_timeout,
(char**) &host, (char**) &unix_socket)) == (char**) &host, (char**) &unix_socket)) ==
INVALID_HANDLE_VALUE) INVALID_HANDLE_VALUE)
{ {
DBUG_PRINT("error", DBUG_PRINT("error",
@ -1986,10 +1995,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
#endif #endif
if (sock == SOCKET_ERROR) if (sock == SOCKET_ERROR)
{ {
net->last_errno=CR_IPSOCK_ERROR; set_mysql_extended_error(mysql, CR_IPSOCK_ERROR, unknown_sqlstate,
strmov(net->sqlstate, unknown_sqlstate); ER(CR_IPSOCK_ERROR), socket_errno);
my_snprintf(net->last_error,sizeof(net->last_error)-1,
ER(net->last_errno),socket_errno);
goto error; goto error;
} }
net->vio= vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ); net->vio= vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ);
@ -2014,10 +2021,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
if (!hp) if (!hp)
{ {
my_gethostbyname_r_free(); my_gethostbyname_r_free();
net->last_errno=CR_UNKNOWN_HOST; set_mysql_extended_error(mysql, CR_UNKNOWN_HOST, unknown_sqlstate,
strmov(net->sqlstate, unknown_sqlstate); ER(CR_UNKNOWN_HOST), host, tmp_errno);
my_snprintf(net->last_error, sizeof(net->last_error)-1,
ER(CR_UNKNOWN_HOST), host, tmp_errno);
goto error; goto error;
} }
memcpy(&sock_addr.sin_addr, hp->h_addr, memcpy(&sock_addr.sin_addr, hp->h_addr,
@ -2030,10 +2035,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
{ {
DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno, DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno,
host)); host));
net->last_errno= CR_CONN_HOST_ERROR; set_mysql_extended_error(mysql, CR_CONN_HOST_ERROR, unknown_sqlstate,
strmov(net->sqlstate, unknown_sqlstate); ER(CR_CONN_HOST_ERROR), host, socket_errno);
my_snprintf(net->last_error, sizeof(net->last_error)-1,
ER(CR_CONN_HOST_ERROR), host, socket_errno);
goto error; goto error;
} }
} }
@ -2097,11 +2100,9 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
PROTOCOL_VERSION, mysql->protocol_version)); PROTOCOL_VERSION, mysql->protocol_version));
if (mysql->protocol_version != PROTOCOL_VERSION) if (mysql->protocol_version != PROTOCOL_VERSION)
{ {
strmov(net->sqlstate, unknown_sqlstate); set_mysql_extended_error(mysql, CR_VERSION_ERROR, unknown_sqlstate,
net->last_errno= CR_VERSION_ERROR; ER(CR_VERSION_ERROR), mysql->protocol_version,
my_snprintf(net->last_error, sizeof(net->last_error)-1, PROTOCOL_VERSION);
ER(CR_VERSION_ERROR), mysql->protocol_version,
PROTOCOL_VERSION);
goto error; goto error;
} }
end=strend((char*) net->read_pos+1); end=strend((char*) net->read_pos+1);
@ -2625,7 +2626,7 @@ void mysql_detach_stmt_list(LIST **stmt_list __attribute__((unused)),
for (; element; element= element->next) for (; element; element= element->next)
{ {
MYSQL_STMT *stmt= (MYSQL_STMT *) element->data; MYSQL_STMT *stmt= (MYSQL_STMT *) element->data;
set_stmt_errmsg(stmt, buff, CR_STMT_CLOSED, unknown_sqlstate); set_stmt_error(stmt, CR_STMT_CLOSED, unknown_sqlstate, buff);
stmt->mysql= 0; stmt->mysql= 0;
/* No need to call list_delete for statement here */ /* No need to call list_delete for statement here */
} }
@ -3142,11 +3143,8 @@ int STDCALL mysql_set_character_set(MYSQL *mysql, const char *cs_name)
{ {
char cs_dir_name[FN_REFLEN]; char cs_dir_name[FN_REFLEN];
get_charsets_dir(cs_dir_name); get_charsets_dir(cs_dir_name);
mysql->net.last_errno= CR_CANT_READ_CHARSET; set_mysql_extended_error(mysql, CR_CANT_READ_CHARSET, unknown_sqlstate,
strmov(mysql->net.sqlstate, unknown_sqlstate); ER(CR_CANT_READ_CHARSET), cs_name, cs_dir_name);
my_snprintf(mysql->net.last_error, sizeof(mysql->net.last_error) - 1,
ER(mysql->net.last_errno), cs_name, cs_dir_name);
} }
charsets_dir= save_csdir; charsets_dir= save_csdir;
return mysql->net.last_errno; return mysql->net.last_errno;

View File

@ -2017,6 +2017,7 @@ end_no_lex_start:
ret= 1; ret= 1;
else else
{ {
ulong saved_master_access;
/* /*
Peculiar initialization order is a crutch to avoid races in SHOW Peculiar initialization order is a crutch to avoid races in SHOW
PROCESSLIST which reads thd->{query/query_length} without a mutex. PROCESSLIST which reads thd->{query/query_length} without a mutex.
@ -2024,8 +2025,19 @@ end_no_lex_start:
thd->query_length= 0; thd->query_length= 0;
thd->query= sp_sql.c_ptr_safe(); thd->query= sp_sql.c_ptr_safe();
thd->query_length= sp_sql.length(); thd->query_length= sp_sql.length();
if (Events::drop_event(thd, dbname, name, FALSE))
ret= 1; /*
NOTE: even if we run in read-only mode, we should be able to lock
the mysql.event table for writing. In order to achieve this, we
should call mysql_lock_tables() under the super-user.
*/
saved_master_access= thd->security_ctx->master_access;
thd->security_ctx->master_access |= SUPER_ACL;
ret= Events::drop_event(thd, dbname, name, FALSE);
thd->security_ctx->master_access= saved_master_access;
} }
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS

View File

@ -525,6 +525,10 @@ Event_db_repository::fill_schema_events(THD *thd, TABLE_LIST *tables,
- whether this open mode would work under LOCK TABLES, or inside a - whether this open mode would work under LOCK TABLES, or inside a
stored function or trigger. stored function or trigger.
Note that if the table can't be locked successfully this operation will
close it. Therefore it provides guarantee that it either opens and locks
table or fails without leaving any tables open.
@param[in] thd Thread context @param[in] thd Thread context
@param[in] lock_type How to lock the table @param[in] lock_type How to lock the table
@param[out] table We will store the open table here @param[out] table We will store the open table here
@ -544,7 +548,10 @@ Event_db_repository::open_event_table(THD *thd, enum thr_lock_type lock_type,
tables.init_one_table("mysql", "event", lock_type); tables.init_one_table("mysql", "event", lock_type);
if (simple_open_n_lock_tables(thd, &tables)) if (simple_open_n_lock_tables(thd, &tables))
{
close_thread_tables(thd);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
}
*table= tables.table; *table= tables.table;
tables.table->use_all_columns(); tables.table->use_all_columns();
@ -995,6 +1002,8 @@ update_timing_fields_for_event(THD *thd,
if (thd->current_stmt_binlog_row_based) if (thd->current_stmt_binlog_row_based)
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
DBUG_ASSERT(thd->security_ctx->master_access & SUPER_ACL);
if (open_event_table(thd, TL_WRITE, &table)) if (open_event_table(thd, TL_WRITE, &table))
goto end; goto end;

View File

@ -399,6 +399,13 @@ Event_scheduler::start()
new_thd->system_thread= SYSTEM_THREAD_EVENT_SCHEDULER; new_thd->system_thread= SYSTEM_THREAD_EVENT_SCHEDULER;
new_thd->command= COM_DAEMON; new_thd->command= COM_DAEMON;
/*
We should run the event scheduler thread under the super-user privileges.
In particular, this is needed to be able to lock the mysql.event table
for writing when the server is running in the read-only mode.
*/
new_thd->security_ctx->master_access |= SUPER_ACL;
scheduler_param_value= scheduler_param_value=
(struct scheduler_param *)my_malloc(sizeof(struct scheduler_param), MYF(0)); (struct scheduler_param *)my_malloc(sizeof(struct scheduler_param), MYF(0));
scheduler_param_value->thd= new_thd; scheduler_param_value->thd= new_thd;

View File

@ -1124,11 +1124,25 @@ Events::load_events_from_db(THD *thd)
READ_RECORD read_record_info; READ_RECORD read_record_info;
bool ret= TRUE; bool ret= TRUE;
uint count= 0; uint count= 0;
ulong saved_master_access;
DBUG_ENTER("Events::load_events_from_db"); DBUG_ENTER("Events::load_events_from_db");
DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd)); DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
if (db_repository->open_event_table(thd, TL_WRITE, &table)) /*
NOTE: even if we run in read-only mode, we should be able to lock the
mysql.event table for writing. In order to achieve this, we should call
mysql_lock_tables() under the super user.
*/
saved_master_access= thd->security_ctx->master_access;
thd->security_ctx->master_access |= SUPER_ACL;
ret= db_repository->open_event_table(thd, TL_WRITE, &table);
thd->security_ctx->master_access= saved_master_access;
if (ret)
{ {
sql_print_error("Event Scheduler: Failed to open table mysql.event"); sql_print_error("Event Scheduler: Failed to open table mysql.event");
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);

View File

@ -555,7 +555,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
else else
file->unlock_row(); file->unlock_row();
/* It does not make sense to read more keys in case of a fatal error */ /* It does not make sense to read more keys in case of a fatal error */
if (thd->net.report_error) if (thd->is_error())
break; break;
} }
if (quick_select) if (quick_select)
@ -573,7 +573,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
file->ha_rnd_end(); file->ha_rnd_end();
} }
if (thd->net.report_error) if (thd->is_error())
DBUG_RETURN(HA_POS_ERROR); DBUG_RETURN(HA_POS_ERROR);
/* Signal we should use orignal column read and write maps */ /* Signal we should use orignal column read and write maps */

View File

@ -325,9 +325,9 @@ Thd_ndb::Thd_ndb()
{ {
ndb= new Ndb(g_ndb_cluster_connection, ""); ndb= new Ndb(g_ndb_cluster_connection, "");
lock_count= 0; lock_count= 0;
start_stmt_count= 0;
count= 0; count= 0;
all= NULL; trans= NULL;
stmt= NULL;
m_error= FALSE; m_error= FALSE;
m_error_code= 0; m_error_code= 0;
query_state&= NDB_QUERY_NORMAL; query_state&= NDB_QUERY_NORMAL;
@ -382,6 +382,11 @@ Thd_ndb::get_open_table(THD *thd, const void *key)
{ {
thd_ndb_share= (THD_NDB_SHARE *) alloc_root(&thd->transaction.mem_root, thd_ndb_share= (THD_NDB_SHARE *) alloc_root(&thd->transaction.mem_root,
sizeof(THD_NDB_SHARE)); sizeof(THD_NDB_SHARE));
if (!thd_ndb_share)
{
mem_alloc_error(sizeof(THD_NDB_SHARE));
DBUG_RETURN(NULL);
}
thd_ndb_share->key= key; thd_ndb_share->key= key;
thd_ndb_share->stat.last_count= count; thd_ndb_share->stat.last_count= count;
thd_ndb_share->stat.no_uncommitted_rows_count= 0; thd_ndb_share->stat.no_uncommitted_rows_count= 0;
@ -1638,6 +1643,26 @@ int ha_ndbcluster::set_primary_key_from_record(NdbOperation *op, const uchar *re
DBUG_RETURN(0); DBUG_RETURN(0);
} }
bool ha_ndbcluster::check_index_fields_in_write_set(uint keyno)
{
KEY* key_info= table->key_info + keyno;
KEY_PART_INFO* key_part= key_info->key_part;
KEY_PART_INFO* end= key_part+key_info->key_parts;
uint i;
DBUG_ENTER("check_index_fields_in_write_set");
for (i= 0; key_part != end; key_part++, i++)
{
Field* field= key_part->field;
if (!bitmap_is_set(table->write_set, field->field_index))
{
DBUG_RETURN(false);
}
}
DBUG_RETURN(true);
}
int ha_ndbcluster::set_index_key_from_record(NdbOperation *op, int ha_ndbcluster::set_index_key_from_record(NdbOperation *op,
const uchar *record, uint keyno) const uchar *record, uint keyno)
{ {
@ -1956,8 +1981,8 @@ check_null_in_record(const KEY* key_info, const uchar *record)
* primary key or unique index values * primary key or unique index values
*/ */
int ha_ndbcluster::peek_indexed_rows(const uchar *record, int ha_ndbcluster::peek_indexed_rows(const uchar *record,
bool check_pk) NDB_WRITE_OP write_op)
{ {
NdbTransaction *trans= m_active_trans; NdbTransaction *trans= m_active_trans;
NdbOperation *op; NdbOperation *op;
@ -1969,7 +1994,7 @@ int ha_ndbcluster::peek_indexed_rows(const uchar *record,
NdbOperation::LockMode lm= NdbOperation::LockMode lm=
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type); (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
first= NULL; first= NULL;
if (check_pk && table->s->primary_key != MAX_KEY) if (write_op != NDB_UPDATE && table->s->primary_key != MAX_KEY)
{ {
/* /*
* Fetch any row with colliding primary key * Fetch any row with colliding primary key
@ -2019,6 +2044,11 @@ int ha_ndbcluster::peek_indexed_rows(const uchar *record,
DBUG_PRINT("info", ("skipping check for key with NULL")); DBUG_PRINT("info", ("skipping check for key with NULL"));
continue; continue;
} }
if (write_op != NDB_INSERT && !check_index_fields_in_write_set(i))
{
DBUG_PRINT("info", ("skipping check for key %u not in write_set", i));
continue;
}
NdbIndexOperation *iop; NdbIndexOperation *iop;
const NDBINDEX *unique_index = m_index[i].unique_index; const NDBINDEX *unique_index = m_index[i].unique_index;
key_part= key_info->key_part; key_part= key_info->key_part;
@ -2716,7 +2746,7 @@ int ha_ndbcluster::write_row(uchar *record)
start_bulk_insert will set parameters to ensure that each start_bulk_insert will set parameters to ensure that each
write_row is committed individually write_row is committed individually
*/ */
int peek_res= peek_indexed_rows(record, TRUE); int peek_res= peek_indexed_rows(record, NDB_INSERT);
if (!peek_res) if (!peek_res)
{ {
@ -2765,7 +2795,7 @@ int ha_ndbcluster::write_row(uchar *record)
if (ndb->getAutoIncrementValue(m_table, g.range, auto_value, 1) == -1) if (ndb->getAutoIncrementValue(m_table, g.range, auto_value, 1) == -1)
{ {
if (--retries && if (--retries &&
ndb->getNdbError().status == NdbError::TemporaryError); ndb->getNdbError().status == NdbError::TemporaryError)
{ {
my_sleep(retry_sleep); my_sleep(retry_sleep);
continue; continue;
@ -2960,7 +2990,8 @@ int ha_ndbcluster::update_row(const uchar *old_data, uchar *new_data)
if (m_ignore_dup_key && (thd->lex->sql_command == SQLCOM_UPDATE || if (m_ignore_dup_key && (thd->lex->sql_command == SQLCOM_UPDATE ||
thd->lex->sql_command == SQLCOM_UPDATE_MULTI)) thd->lex->sql_command == SQLCOM_UPDATE_MULTI))
{ {
int peek_res= peek_indexed_rows(new_data, pk_update); NDB_WRITE_OP write_op= (pk_update) ? NDB_PK_UPDATE : NDB_UPDATE;
int peek_res= peek_indexed_rows(new_data, write_op);
if (!peek_res) if (!peek_res)
{ {
@ -4327,7 +4358,7 @@ static int ndbcluster_update_apply_status(THD *thd, int do_update)
Ndb *ndb= thd_ndb->ndb; Ndb *ndb= thd_ndb->ndb;
NDBDICT *dict= ndb->getDictionary(); NDBDICT *dict= ndb->getDictionary();
const NDBTAB *ndbtab; const NDBTAB *ndbtab;
NdbTransaction *trans= thd_ndb->all ? thd_ndb->all : thd_ndb->stmt; NdbTransaction *trans= thd_ndb->trans;
ndb->setDatabaseName(NDB_REP_DB); ndb->setDatabaseName(NDB_REP_DB);
Ndb_table_guard ndbtab_g(dict, NDB_APPLY_TABLE); Ndb_table_guard ndbtab_g(dict, NDB_APPLY_TABLE);
if (!(ndbtab= ndbtab_g.get_table())) if (!(ndbtab= ndbtab_g.get_table()))
@ -4371,10 +4402,110 @@ static int ndbcluster_update_apply_status(THD *thd, int do_update)
} }
#endif /* HAVE_NDB_BINLOG */ #endif /* HAVE_NDB_BINLOG */
void ha_ndbcluster::transaction_checks(THD *thd)
{
if (thd->lex->sql_command == SQLCOM_LOAD)
{
m_transaction_on= FALSE;
/* Would be simpler if has_transactions() didn't always say "yes" */
thd->transaction.all.modified_non_trans_table=
thd->transaction.stmt.modified_non_trans_table= TRUE;
}
else if (!thd->transaction.on)
m_transaction_on= FALSE;
else
m_transaction_on= thd->variables.ndb_use_transactions;
}
int ha_ndbcluster::start_statement(THD *thd,
Thd_ndb *thd_ndb,
Ndb *ndb)
{
DBUG_ENTER("ha_ndbcluster::start_statement");
PRINT_OPTION_FLAGS(thd);
trans_register_ha(thd, FALSE, ndbcluster_hton);
if (!thd_ndb->trans)
{
if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
trans_register_ha(thd, TRUE, ndbcluster_hton);
DBUG_PRINT("trans",("Starting transaction"));
thd_ndb->trans= ndb->startTransaction();
if (thd_ndb->trans == NULL)
ERR_RETURN(ndb->getNdbError());
thd_ndb->init_open_tables();
thd_ndb->query_state&= NDB_QUERY_NORMAL;
thd_ndb->trans_options= 0;
thd_ndb->m_slow_path= FALSE;
if (!(thd->options & OPTION_BIN_LOG) ||
thd->variables.binlog_format == BINLOG_FORMAT_STMT)
{
thd_ndb->trans_options|= TNTO_NO_LOGGING;
thd_ndb->m_slow_path= TRUE;
}
else if (thd->slave_thread)
thd_ndb->m_slow_path= TRUE;
}
/*
If this is the start of a LOCK TABLE, a table look
should be taken on the table in NDB
Check if it should be read or write lock
*/
if (thd->options & (OPTION_TABLE_LOCK))
{
//lockThisTable();
DBUG_PRINT("info", ("Locking the table..." ));
}
DBUG_RETURN(0);
}
int ha_ndbcluster::init_handler_for_statement(THD *thd, Thd_ndb *thd_ndb)
{
/*
This is the place to make sure this handler instance
has a started transaction.
The transaction is started by the first handler on which
MySQL Server calls external lock
Other handlers in the same stmt or transaction should use
the same NDB transaction. This is done by setting up the m_active_trans
pointer to point to the NDB transaction.
*/
DBUG_ENTER("ha_ndbcluster::init_handler_for_statement");
// store thread specific data first to set the right context
m_force_send= thd->variables.ndb_force_send;
m_ha_not_exact_count= !thd->variables.ndb_use_exact_count;
m_autoincrement_prefetch=
(ha_rows) thd->variables.ndb_autoincrement_prefetch_sz;
m_active_trans= thd_ndb->trans;
DBUG_ASSERT(m_active_trans);
// Start of transaction
m_rows_changed= 0;
m_ops_pending= 0;
m_slow_path= thd_ndb->m_slow_path;
#ifdef HAVE_NDB_BINLOG
if (unlikely(m_slow_path))
{
if (m_share == ndb_apply_status_share && thd->slave_thread)
thd_ndb->trans_options|= TNTO_INJECTED_APPLY_STATUS;
}
#endif
// TODO remove double pointers...
if (!(m_thd_ndb_share= thd_ndb->get_open_table(thd, m_table)))
{
DBUG_RETURN(1);
}
m_table_info= &m_thd_ndb_share->stat;
DBUG_RETURN(0);
}
int ha_ndbcluster::external_lock(THD *thd, int lock_type) int ha_ndbcluster::external_lock(THD *thd, int lock_type)
{ {
int error=0; int error=0;
NdbTransaction* trans= NULL;
DBUG_ENTER("external_lock"); DBUG_ENTER("external_lock");
/* /*
@ -4395,124 +4526,15 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
if (lock_type != F_UNLCK) if (lock_type != F_UNLCK)
{ {
DBUG_PRINT("info", ("lock_type != F_UNLCK")); DBUG_PRINT("info", ("lock_type != F_UNLCK"));
if (thd->lex->sql_command == SQLCOM_LOAD) transaction_checks(thd);
{
m_transaction_on= FALSE;
/* Would be simpler if has_transactions() didn't always say "yes" */
thd->transaction.all.modified_non_trans_table= thd->transaction.stmt.modified_non_trans_table= TRUE;
}
else if (!thd->transaction.on)
m_transaction_on= FALSE;
else
m_transaction_on= thd->variables.ndb_use_transactions;
if (!thd_ndb->lock_count++) if (!thd_ndb->lock_count++)
{ {
PRINT_OPTION_FLAGS(thd); if ((error= start_statement(thd, thd_ndb, ndb)))
if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) goto error;
{
// Autocommit transaction
DBUG_ASSERT(!thd_ndb->stmt);
DBUG_PRINT("trans",("Starting transaction stmt"));
trans= ndb->startTransaction();
if (trans == NULL)
{
thd_ndb->lock_count= 0;
ERR_RETURN(ndb->getNdbError());
}
thd_ndb->init_open_tables();
thd_ndb->stmt= trans;
thd_ndb->query_state&= NDB_QUERY_NORMAL;
thd_ndb->trans_options= 0;
thd_ndb->m_slow_path= FALSE;
if (!(thd->options & OPTION_BIN_LOG) ||
thd->variables.binlog_format == BINLOG_FORMAT_STMT)
{
thd_ndb->trans_options|= TNTO_NO_LOGGING;
thd_ndb->m_slow_path= TRUE;
}
else if (thd->slave_thread)
thd_ndb->m_slow_path= TRUE;
trans_register_ha(thd, FALSE, ndbcluster_hton);
}
else
{
if (!thd_ndb->all)
{
// Not autocommit transaction
// A "master" transaction ha not been started yet
DBUG_PRINT("trans",("starting transaction, all"));
trans= ndb->startTransaction();
if (trans == NULL)
{
thd_ndb->lock_count= 0;
ERR_RETURN(ndb->getNdbError());
}
thd_ndb->init_open_tables();
thd_ndb->all= trans;
thd_ndb->query_state&= NDB_QUERY_NORMAL;
thd_ndb->trans_options= 0;
thd_ndb->m_slow_path= FALSE;
if (!(thd->options & OPTION_BIN_LOG) ||
thd->variables.binlog_format == BINLOG_FORMAT_STMT)
{
thd_ndb->trans_options|= TNTO_NO_LOGGING;
thd_ndb->m_slow_path= TRUE;
}
else if (thd->slave_thread)
thd_ndb->m_slow_path= TRUE;
trans_register_ha(thd, TRUE, ndbcluster_hton);
/*
If this is the start of a LOCK TABLE, a table look
should be taken on the table in NDB
Check if it should be read or write lock
*/
if (thd->options & (OPTION_TABLE_LOCK))
{
//lockThisTable();
DBUG_PRINT("info", ("Locking the table..." ));
}
}
}
} }
/* if ((error= init_handler_for_statement(thd, thd_ndb)))
This is the place to make sure this handler instance goto error;
has a started transaction. DBUG_RETURN(0);
The transaction is started by the first handler on which
MySQL Server calls external lock
Other handlers in the same stmt or transaction should use
the same NDB transaction. This is done by setting up the m_active_trans
pointer to point to the NDB transaction.
*/
// store thread specific data first to set the right context
m_force_send= thd->variables.ndb_force_send;
m_ha_not_exact_count= !thd->variables.ndb_use_exact_count;
m_autoincrement_prefetch=
(ha_rows) thd->variables.ndb_autoincrement_prefetch_sz;
m_active_trans= thd_ndb->all ? thd_ndb->all : thd_ndb->stmt;
DBUG_ASSERT(m_active_trans);
// Start of transaction
m_rows_changed= 0;
m_ops_pending= 0;
m_slow_path= thd_ndb->m_slow_path;
#ifdef HAVE_NDB_BINLOG
if (unlikely(m_slow_path))
{
if (m_share == ndb_apply_status_share && thd->slave_thread)
thd_ndb->trans_options|= TNTO_INJECTED_APPLY_STATUS;
}
#endif
// TODO remove double pointers...
m_thd_ndb_share= thd_ndb->get_open_table(thd, m_table);
m_table_info= &m_thd_ndb_share->stat;
} }
else else
{ {
@ -4540,16 +4562,19 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
DBUG_PRINT("trans", ("Last external_lock")); DBUG_PRINT("trans", ("Last external_lock"));
PRINT_OPTION_FLAGS(thd); PRINT_OPTION_FLAGS(thd);
if (thd_ndb->stmt) if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{ {
/* if (thd_ndb->trans)
Unlock is done without a transaction commit / rollback. {
This happens if the thread didn't update any rows /*
We must in this case close the transaction to release resources Unlock is done without a transaction commit / rollback.
*/ This happens if the thread didn't update any rows
DBUG_PRINT("trans",("ending non-updating transaction")); We must in this case close the transaction to release resources
ndb->closeTransaction(m_active_trans); */
thd_ndb->stmt= NULL; DBUG_PRINT("trans",("ending non-updating transaction"));
ndb->closeTransaction(thd_ndb->trans);
thd_ndb->trans= NULL;
}
} }
} }
m_table_info= NULL; m_table_info= NULL;
@ -4578,7 +4603,10 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
if (m_ops_pending) if (m_ops_pending)
DBUG_PRINT("warning", ("ops_pending != 0L")); DBUG_PRINT("warning", ("ops_pending != 0L"));
m_ops_pending= 0; m_ops_pending= 0;
DBUG_RETURN(0);
} }
error:
thd_ndb->lock_count--;
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@ -4610,25 +4638,20 @@ int ha_ndbcluster::start_stmt(THD *thd, thr_lock_type lock_type)
{ {
int error=0; int error=0;
DBUG_ENTER("start_stmt"); DBUG_ENTER("start_stmt");
PRINT_OPTION_FLAGS(thd);
Thd_ndb *thd_ndb= get_thd_ndb(thd); Thd_ndb *thd_ndb= get_thd_ndb(thd);
NdbTransaction *trans= (thd_ndb->stmt)?thd_ndb->stmt:thd_ndb->all; transaction_checks(thd);
if (!trans){ if (!thd_ndb->start_stmt_count++)
{
Ndb *ndb= thd_ndb->ndb; Ndb *ndb= thd_ndb->ndb;
DBUG_PRINT("trans",("Starting transaction stmt")); if ((error= start_statement(thd, thd_ndb, ndb)))
trans= ndb->startTransaction(); goto error;
if (trans == NULL)
ERR_RETURN(ndb->getNdbError());
no_uncommitted_rows_reset(thd);
thd_ndb->stmt= trans;
thd_ndb->query_state&= NDB_QUERY_NORMAL;
trans_register_ha(thd, FALSE, ndbcluster_hton);
} }
m_active_trans= trans; if ((error= init_handler_for_statement(thd, thd_ndb)))
// Start of statement goto error;
m_ops_pending= 0; DBUG_RETURN(0);
error:
thd_ndb->start_stmt_count--;
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@ -4642,15 +4665,29 @@ static int ndbcluster_commit(handlerton *hton, THD *thd, bool all)
int res= 0; int res= 0;
Thd_ndb *thd_ndb= get_thd_ndb(thd); Thd_ndb *thd_ndb= get_thd_ndb(thd);
Ndb *ndb= thd_ndb->ndb; Ndb *ndb= thd_ndb->ndb;
NdbTransaction *trans= all ? thd_ndb->all : thd_ndb->stmt; NdbTransaction *trans= thd_ndb->trans;
DBUG_ENTER("ndbcluster_commit"); DBUG_ENTER("ndbcluster_commit");
DBUG_PRINT("transaction",("%s",
trans == thd_ndb->stmt ?
"stmt" : "all"));
DBUG_ASSERT(ndb); DBUG_ASSERT(ndb);
if (trans == NULL) PRINT_OPTION_FLAGS(thd);
DBUG_PRINT("enter", ("Commit %s", (all ? "all" : "stmt")));
thd_ndb->start_stmt_count= 0;
if (trans == NULL || (!all &&
thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
/*
An odditity in the handler interface is that commit on handlerton
is called to indicate end of statement only in cases where
autocommit isn't used and the all flag isn't set.
We also leave quickly when a transaction haven't even been started,
in this case we are safe that no clean up is needed. In this case
the MySQL Server could handle the query without contacting the
NDB kernel.
*/
DBUG_PRINT("info", ("Commit before start or end-of-statement only"));
DBUG_RETURN(0); DBUG_RETURN(0);
}
#ifdef HAVE_NDB_BINLOG #ifdef HAVE_NDB_BINLOG
if (unlikely(thd_ndb->m_slow_path)) if (unlikely(thd_ndb->m_slow_path))
@ -4671,11 +4708,7 @@ static int ndbcluster_commit(handlerton *hton, THD *thd, bool all)
ndbcluster_print_error(res, error_op); ndbcluster_print_error(res, error_op);
} }
ndb->closeTransaction(trans); ndb->closeTransaction(trans);
thd_ndb->trans= NULL;
if (all)
thd_ndb->all= NULL;
else
thd_ndb->stmt= NULL;
/* Clear commit_count for tables changed by transaction */ /* Clear commit_count for tables changed by transaction */
NDB_SHARE* share; NDB_SHARE* share;
@ -4704,13 +4737,18 @@ static int ndbcluster_rollback(handlerton *hton, THD *thd, bool all)
int res= 0; int res= 0;
Thd_ndb *thd_ndb= get_thd_ndb(thd); Thd_ndb *thd_ndb= get_thd_ndb(thd);
Ndb *ndb= thd_ndb->ndb; Ndb *ndb= thd_ndb->ndb;
NdbTransaction *trans= all ? thd_ndb->all : thd_ndb->stmt; NdbTransaction *trans= thd_ndb->trans;
DBUG_ENTER("ndbcluster_rollback"); DBUG_ENTER("ndbcluster_rollback");
DBUG_PRINT("transaction",("%s", DBUG_ASSERT(ndb);
trans == thd_ndb->stmt ? thd_ndb->start_stmt_count= 0;
"stmt" : "all")); if (trans == NULL || (!all &&
DBUG_ASSERT(ndb && trans); thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
/* Ignore end-of-statement until real rollback or commit is called */
DBUG_PRINT("info", ("Rollback before start or end-of-statement only"));
DBUG_RETURN(0);
}
if (trans->execute(NdbTransaction::Rollback) != 0) if (trans->execute(NdbTransaction::Rollback) != 0)
{ {
@ -4722,11 +4760,7 @@ static int ndbcluster_rollback(handlerton *hton, THD *thd, bool all)
ndbcluster_print_error(res, error_op); ndbcluster_print_error(res, error_op);
} }
ndb->closeTransaction(trans); ndb->closeTransaction(trans);
thd_ndb->trans= NULL;
if (all)
thd_ndb->all= NULL;
else
thd_ndb->stmt= NULL;
/* Clear list of tables changed by transaction */ /* Clear list of tables changed by transaction */
thd_ndb->changed_tables.empty(); thd_ndb->changed_tables.empty();
@ -6155,7 +6189,7 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment,
ndb->getAutoIncrementValue(m_table, g.range, auto_value, cache_size, increment, offset)) ndb->getAutoIncrementValue(m_table, g.range, auto_value, cache_size, increment, offset))
{ {
if (--retries && if (--retries &&
ndb->getNdbError().status == NdbError::TemporaryError); ndb->getNdbError().status == NdbError::TemporaryError)
{ {
my_sleep(retry_sleep); my_sleep(retry_sleep);
continue; continue;

View File

@ -81,6 +81,12 @@ typedef struct ndb_index_data {
uint index_stat_query_count; uint index_stat_query_count;
} NDB_INDEX_DATA; } NDB_INDEX_DATA;
typedef enum ndb_write_op {
NDB_INSERT = 0,
NDB_UPDATE = 1,
NDB_PK_UPDATE = 2
} NDB_WRITE_OP;
typedef union { const NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue; typedef union { const NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue;
int get_ndb_blobs_value(TABLE* table, NdbValue* value_array, int get_ndb_blobs_value(TABLE* table, NdbValue* value_array,
@ -204,8 +210,8 @@ class Thd_ndb
Ndb *ndb; Ndb *ndb;
ulong count; ulong count;
uint lock_count; uint lock_count;
NdbTransaction *all; uint start_stmt_count;
NdbTransaction *stmt; NdbTransaction *trans;
bool m_error; bool m_error;
bool m_slow_path; bool m_slow_path;
int m_error_code; int m_error_code;
@ -438,7 +444,7 @@ private:
const NdbOperation *first, const NdbOperation *first,
const NdbOperation *last, const NdbOperation *last,
uint errcode); uint errcode);
int peek_indexed_rows(const uchar *record, bool check_pk); int peek_indexed_rows(const uchar *record, NDB_WRITE_OP write_op);
int fetch_next(NdbScanOperation* op); int fetch_next(NdbScanOperation* op);
int next_result(uchar *buf); int next_result(uchar *buf);
int define_read_attrs(uchar* buf, NdbOperation* op); int define_read_attrs(uchar* buf, NdbOperation* op);
@ -463,6 +469,7 @@ private:
friend int g_get_ndb_blobs_value(NdbBlob *ndb_blob, void *arg); friend int g_get_ndb_blobs_value(NdbBlob *ndb_blob, void *arg);
int set_primary_key(NdbOperation *op, const uchar *key); int set_primary_key(NdbOperation *op, const uchar *key);
int set_primary_key_from_record(NdbOperation *op, const uchar *record); int set_primary_key_from_record(NdbOperation *op, const uchar *record);
bool check_index_fields_in_write_set(uint keyno);
int set_index_key_from_record(NdbOperation *op, const uchar *record, int set_index_key_from_record(NdbOperation *op, const uchar *record,
uint keyno); uint keyno);
int set_bounds(NdbIndexScanOperation*, uint inx, bool rir, int set_bounds(NdbIndexScanOperation*, uint inx, bool rir,
@ -496,6 +503,10 @@ private:
friend int execute_no_commit(ha_ndbcluster*, NdbTransaction*, bool); friend int execute_no_commit(ha_ndbcluster*, NdbTransaction*, bool);
friend int execute_no_commit_ie(ha_ndbcluster*, NdbTransaction*, bool); friend int execute_no_commit_ie(ha_ndbcluster*, NdbTransaction*, bool);
void transaction_checks(THD *thd);
int start_statement(THD *thd, Thd_ndb *thd_ndb, Ndb* ndb);
int init_handler_for_statement(THD *thd, Thd_ndb *thd_ndb);
NdbTransaction *m_active_trans; NdbTransaction *m_active_trans;
NdbScanOperation *m_active_cursor; NdbScanOperation *m_active_cursor;
const NdbDictionary::Table *m_table; const NdbDictionary::Table *m_table;

View File

@ -259,7 +259,7 @@ static void run_query(THD *thd, char *buf, char *end,
DBUG_PRINT("query", ("%s", thd->query)); DBUG_PRINT("query", ("%s", thd->query));
mysql_parse(thd, thd->query, thd->query_length, &found_semicolon); mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
if (no_print_error && thd->query_error) if (no_print_error && thd->is_slave_error)
{ {
int i; int i;
Thd_ndb *thd_ndb= get_thd_ndb(thd); Thd_ndb *thd_ndb= get_thd_ndb(thd);
@ -271,7 +271,7 @@ static void run_query(THD *thd, char *buf, char *end,
sql_print_error("NDB: %s: error %s %d(ndb: %d) %d %d", sql_print_error("NDB: %s: error %s %d(ndb: %d) %d %d",
buf, thd->net.last_error, thd->net.last_errno, buf, thd->net.last_error, thd->net.last_errno,
thd_ndb->m_error_code, thd_ndb->m_error_code,
thd->net.report_error, thd->query_error); (int) thd->is_error(), thd->is_slave_error);
} }
thd->options= save_thd_options; thd->options= save_thd_options;

View File

@ -1338,9 +1338,23 @@ ha_ndbcluster_cond::generate_scan_filter(NdbScanOperation *op)
if (m_cond_stack) if (m_cond_stack)
{ {
NdbScanFilter filter(op); NdbScanFilter filter(op, false); // don't abort on too large
DBUG_RETURN(generate_scan_filter_from_cond(filter)); int ret=generate_scan_filter_from_cond(filter);
if (ret != 0)
{
const NdbError& err=filter.getNdbError();
if (err.code == NdbScanFilter::FilterTooLarge)
{
// err.message has static storage
DBUG_PRINT("info", ("%s", err.message));
push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
err.code, err.message);
ret=0;
}
}
if (ret != 0)
DBUG_RETURN(ret);
} }
else else
{ {
@ -1391,7 +1405,7 @@ int ha_ndbcluster_cond::generate_scan_filter_from_key(NdbScanOperation *op,
{ {
KEY_PART_INFO* key_part= key_info->key_part; KEY_PART_INFO* key_part= key_info->key_part;
KEY_PART_INFO* end= key_part+key_info->key_parts; KEY_PART_INFO* end= key_part+key_info->key_parts;
NdbScanFilter filter(op); NdbScanFilter filter(op, true); // abort on too large
int res; int res;
DBUG_ENTER("generate_scan_filter_from_key"); DBUG_ENTER("generate_scan_filter_from_key");

View File

@ -1414,6 +1414,36 @@ static const char *check_lowercase_names(handler *file, const char *path,
} }
/**
An interceptor to hijack the text of the error message without
setting an error in the thread. We need the text to present it
in the form of a warning to the user.
*/
struct Ha_delete_table_error_handler: public Internal_error_handler
{
public:
virtual bool handle_error(uint sql_errno,
const char *message,
MYSQL_ERROR::enum_warning_level level,
THD *thd);
char buff[MYSQL_ERRMSG_SIZE];
};
bool
Ha_delete_table_error_handler::
handle_error(uint sql_errno,
const char *message,
MYSQL_ERROR::enum_warning_level level,
THD *thd)
{
/* Grab the error message */
strmake(buff, message, sizeof(buff)-1);
return TRUE;
}
/** @brief /** @brief
This should return ENOENT if the file doesn't exists. This should return ENOENT if the file doesn't exists.
The .frm file will be deleted only if we return 0 or ENOENT The .frm file will be deleted only if we return 0 or ENOENT
@ -1442,23 +1472,11 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
{ {
/* /*
Because file->print_error() use my_error() to generate the error message Because file->print_error() use my_error() to generate the error message
we must store the error state in thd, reset it and restore it to we use an internal error handler to intercept it and store the text
be able to get hold of the error message. in a temporary buffer. Later the message will be presented to user
(We should in the future either rewrite handler::print_error() or make as a warning.
a nice method of this.
*/ */
bool query_error= thd->query_error; Ha_delete_table_error_handler ha_delete_table_error_handler;
sp_rcontext *spcont= thd->spcont;
SELECT_LEX *current_select= thd->lex->current_select;
char buff[sizeof(thd->net.last_error)];
char new_error[sizeof(thd->net.last_error)];
int last_errno= thd->net.last_errno;
strmake(buff, thd->net.last_error, sizeof(buff)-1);
thd->query_error= 0;
thd->spcont= NULL;
thd->lex->current_select= 0;
thd->net.last_error[0]= 0;
/* Fill up strucutures that print_error may need */ /* Fill up strucutures that print_error may need */
dummy_share.path.str= (char*) path; dummy_share.path.str= (char*) path;
@ -1471,16 +1489,18 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
file->table_share= &dummy_share; file->table_share= &dummy_share;
file->table= &dummy_table; file->table= &dummy_table;
file->print_error(error, 0);
strmake(new_error, thd->net.last_error, sizeof(buff)-1);
/* restore thd */ thd->push_internal_handler(&ha_delete_table_error_handler);
thd->query_error= query_error; file->print_error(error, 0);
thd->spcont= spcont;
thd->lex->current_select= current_select; thd->pop_internal_handler();
thd->net.last_errno= last_errno;
strmake(thd->net.last_error, buff, sizeof(buff)-1); /*
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, new_error); XXX: should we convert *all* errors to warnings here?
What if the error is fatal?
*/
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error,
ha_delete_table_error_handler.buff);
} }
delete file; delete file;
DBUG_RETURN(error); DBUG_RETURN(error);
@ -2203,7 +2223,7 @@ void handler::print_error(int error, myf errflag)
case HA_ERR_NO_SUCH_TABLE: case HA_ERR_NO_SUCH_TABLE:
my_error(ER_NO_SUCH_TABLE, MYF(0), table_share->db.str, my_error(ER_NO_SUCH_TABLE, MYF(0), table_share->db.str,
table_share->table_name.str); table_share->table_name.str);
break; DBUG_VOID_RETURN;
case HA_ERR_RBR_LOGGING_FAILED: case HA_ERR_RBR_LOGGING_FAILED:
textno= ER_BINLOG_ROW_LOGGING_FAILED; textno= ER_BINLOG_ROW_LOGGING_FAILED;
break; break;
@ -2641,8 +2661,7 @@ int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
frmblob and frmlen are set, write the frm to disk frmblob and frmlen are set, write the frm to disk
*/ */
(void)strxnmov(path,FN_REFLEN-1,mysql_data_home,FN_ROOTDIR, build_table_filename(path, FN_REFLEN-1, db, name, "", 0);
db,FN_ROOTDIR,name,NullS);
// Save the frm file // Save the frm file
error= writefrm(path, frmblob, frmlen); error= writefrm(path, frmblob, frmlen);
my_free(frmblob, MYF(0)); my_free(frmblob, MYF(0));

View File

@ -187,7 +187,7 @@ Item_func::fix_fields(THD *thd, Item **ref)
} }
} }
fix_length_and_dec(); fix_length_and_dec();
if (thd->net.report_error) // An error inside fix_length_and_dec occured if (thd->is_error()) // An error inside fix_length_and_dec occured
return TRUE; return TRUE;
fixed= 1; fixed= 1;
return FALSE; return FALSE;
@ -2897,6 +2897,7 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
if (u_d->func_init) if (u_d->func_init)
{ {
char init_msg_buff[MYSQL_ERRMSG_SIZE];
char *to=num_buffer; char *to=num_buffer;
for (uint i=0; i < arg_count; i++) for (uint i=0; i < arg_count; i++)
{ {
@ -2949,10 +2950,10 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
} }
thd->net.last_error[0]=0; thd->net.last_error[0]=0;
Udf_func_init init= u_d->func_init; Udf_func_init init= u_d->func_init;
if ((error=(uchar) init(&initid, &f_args, thd->net.last_error))) if ((error=(uchar) init(&initid, &f_args, init_msg_buff)))
{ {
my_error(ER_CANT_INITIALIZE_UDF, MYF(0), my_error(ER_CANT_INITIALIZE_UDF, MYF(0),
u_d->name.str, thd->net.last_error); u_d->name.str, init_msg_buff);
free_udf(u_d); free_udf(u_d);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@ -4073,7 +4074,7 @@ my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
NOTES NOTES
For now it always return OK. All problem with value evaluating For now it always return OK. All problem with value evaluating
will be caught by thd->net.report_error check in sql_set_variables(). will be caught by thd->is_error() check in sql_set_variables().
RETURN RETURN
FALSE OK. FALSE OK.

View File

@ -248,7 +248,7 @@ bool Item_subselect::exec()
{ {
int res; int res;
if (thd->net.report_error) if (thd->is_error())
/* Do not execute subselect in case of a fatal error */ /* Do not execute subselect in case of a fatal error */
return 1; return 1;

View File

@ -72,13 +72,14 @@ public:
virtual ~Silence_log_table_errors() {} virtual ~Silence_log_table_errors() {}
virtual bool handle_error(uint sql_errno, virtual bool handle_error(uint sql_errno, const char *message,
MYSQL_ERROR::enum_warning_level level, MYSQL_ERROR::enum_warning_level level,
THD *thd); THD *thd);
}; };
bool bool
Silence_log_table_errors::handle_error(uint /* sql_errno */, Silence_log_table_errors::handle_error(uint /* sql_errno */,
const char * /* message */,
MYSQL_ERROR::enum_warning_level /* level */, MYSQL_ERROR::enum_warning_level /* level */,
THD * /* thd */) THD * /* thd */)
{ {
@ -2891,8 +2892,8 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
*decrease_log_space-= file_size; *decrease_log_space-= file_size;
ha_binlog_index_purge_file(current_thd, log_info.log_file_name); ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
if (current_thd->query_error) { if (current_thd->is_slave_error) {
DBUG_PRINT("info",("query error: %d", current_thd->query_error)); DBUG_PRINT("info",("slave error: %d", current_thd->is_slave_error));
if (my_errno == EMFILE) { if (my_errno == EMFILE) {
DBUG_PRINT("info",("my_errno: %d, set ret = LOG_INFO_EMFILE", my_errno)); DBUG_PRINT("info",("my_errno: %d, set ret = LOG_INFO_EMFILE", my_errno));
ret = LOG_INFO_EMFILE; ret = LOG_INFO_EMFILE;

View File

@ -148,7 +148,7 @@ static void pretty_print_str(IO_CACHE* cache, char* str, int len)
static void clear_all_errors(THD *thd, Relay_log_info *rli) static void clear_all_errors(THD *thd, Relay_log_info *rli)
{ {
thd->query_error = 0; thd->is_slave_error = 0;
thd->clear_error(); thd->clear_error();
rli->clear_error(); rli->clear_error();
} }
@ -2106,7 +2106,7 @@ and was aborted. There is a chance that your master is inconsistent at this \
point. If you are sure that your master is ok, run this query manually on the \ point. If you are sure that your master is ok, run this query manually on the \
slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \ slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
START SLAVE; . Query: '%s'", expected_error, thd->query); START SLAVE; . Query: '%s'", expected_error, thd->query);
thd->query_error= 1; thd->is_slave_error= 1;
} }
goto end; goto end;
} }
@ -2138,7 +2138,7 @@ Default database: '%s'. Query: '%s'",
actual_error ? thd->net.last_error: "no error", actual_error ? thd->net.last_error: "no error",
actual_error, actual_error,
print_slave_db_safe(db), query_arg); print_slave_db_safe(db), query_arg);
thd->query_error= 1; thd->is_slave_error= 1;
} }
/* /*
If we get the same error code as expected, or they should be ignored. If we get the same error code as expected, or they should be ignored.
@ -2153,14 +2153,14 @@ Default database: '%s'. Query: '%s'",
/* /*
Other cases: mostly we expected no error and get one. Other cases: mostly we expected no error and get one.
*/ */
else if (thd->query_error || thd->is_fatal_error) else if (thd->is_slave_error || thd->is_fatal_error)
{ {
rli->report(ERROR_LEVEL, actual_error, rli->report(ERROR_LEVEL, actual_error,
"Error '%s' on query. Default database: '%s'. Query: '%s'", "Error '%s' on query. Default database: '%s'. Query: '%s'",
(actual_error ? thd->net.last_error : (actual_error ? thd->net.last_error :
"unexpected success or fatal error"), "unexpected success or fatal error"),
print_slave_db_safe(thd->db), query_arg); print_slave_db_safe(thd->db), query_arg);
thd->query_error= 1; thd->is_slave_error= 1;
} }
/* /*
@ -2171,7 +2171,7 @@ Default database: '%s'. Query: '%s'",
sql_print_error("Slave: did not get the expected number of affected \ sql_print_error("Slave: did not get the expected number of affected \
rows running query from master - expected %d, got %d (this numbers \ rows running query from master - expected %d, got %d (this numbers \
should have matched modulo 4294967296).", 0, ...); should have matched modulo 4294967296).", 0, ...);
thd->query_error = 1; thd->is_slave_error = 1;
} }
We may also want an option to tell the slave to ignore "affected" We may also want an option to tell the slave to ignore "affected"
mismatch. This mismatch could be implemented with a new ER_ code, and mismatch. This mismatch could be implemented with a new ER_ code, and
@ -2215,7 +2215,7 @@ end:
thd->first_successful_insert_id_in_prev_stmt= 0; thd->first_successful_insert_id_in_prev_stmt= 0;
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0; thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
return thd->query_error; return thd->is_slave_error;
} }
int Query_log_event::do_update_pos(Relay_log_info *rli) int Query_log_event::do_update_pos(Relay_log_info *rli)
@ -3255,7 +3255,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
thd->set_db(new_db.str, new_db.length); thd->set_db(new_db.str, new_db.length);
DBUG_ASSERT(thd->query == 0); DBUG_ASSERT(thd->query == 0);
thd->query_length= 0; // Should not be needed thd->query_length= 0; // Should not be needed
thd->query_error= 0; thd->is_slave_error= 0;
clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
/* see Query_log_event::do_apply_event() and BUG#13360 */ /* see Query_log_event::do_apply_event() and BUG#13360 */
@ -3429,7 +3429,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
List<Item> tmp_list; List<Item> tmp_list;
if (mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list, if (mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
handle_dup, ignore, net != 0)) handle_dup, ignore, net != 0))
thd->query_error= 1; thd->is_slave_error= 1;
if (thd->cuted_fields) if (thd->cuted_fields)
{ {
/* log_pos is the position of the LOAD event in the master log */ /* log_pos is the position of the LOAD event in the master log */
@ -3468,9 +3468,9 @@ error:
close_thread_tables(thd); close_thread_tables(thd);
DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error", DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error",
thd->query_error= 0; thd->is_fatal_error= 1;); thd->is_slave_error= 0; thd->is_fatal_error= 1;);
if (thd->query_error) if (thd->is_slave_error)
{ {
/* this err/sql_errno code is copy-paste from net_send_error() */ /* this err/sql_errno code is copy-paste from net_send_error() */
const char *err; const char *err;
@ -5655,7 +5655,7 @@ Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
m_width(tbl_arg ? tbl_arg->s->fields : 1), m_width(tbl_arg ? tbl_arg->s->fields : 1),
m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0) m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0)
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
,m_key(NULL), m_curr_row(NULL), m_curr_row_end(NULL) , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
#endif #endif
{ {
/* /*
@ -5703,7 +5703,7 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
#endif #endif
m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0) m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0)
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
,m_key(NULL), m_curr_row(NULL), m_curr_row_end(NULL) , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
#endif #endif
{ {
DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)"); DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)");
@ -5951,7 +5951,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
{ {
if (!need_reopen) if (!need_reopen)
{ {
if (thd->query_error || thd->is_fatal_error) if (thd->is_slave_error || thd->is_fatal_error)
{ {
/* /*
Error reporting borrowed from Query_log_event with many excessive Error reporting borrowed from Query_log_event with many excessive
@ -5995,7 +5995,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
uint tables_count= rli->tables_to_lock_count; uint tables_count= rli->tables_to_lock_count;
if ((error= open_tables(thd, &tables, &tables_count, 0))) if ((error= open_tables(thd, &tables, &tables_count, 0)))
{ {
if (thd->query_error || thd->is_fatal_error) if (thd->is_slave_error || thd->is_fatal_error)
{ {
/* /*
Error reporting borrowed from Query_log_event with many excessive Error reporting borrowed from Query_log_event with many excessive
@ -6006,7 +6006,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
"Error '%s' on reopening tables", "Error '%s' on reopening tables",
(actual_error ? thd->net.last_error : (actual_error ? thd->net.last_error :
"unexpected success or fatal error")); "unexpected success or fatal error"));
thd->query_error= 1; thd->is_slave_error= 1;
} }
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
DBUG_RETURN(error); DBUG_RETURN(error);
@ -6029,7 +6029,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
{ {
mysql_unlock_tables(thd, thd->lock); mysql_unlock_tables(thd, thd->lock);
thd->lock= 0; thd->lock= 0;
thd->query_error= 1; thd->is_slave_error= 1;
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
DBUG_RETURN(ERR_BAD_TABLE_DEF); DBUG_RETURN(ERR_BAD_TABLE_DEF);
} }
@ -6159,7 +6159,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
"Error in %s event: row application failed. %s", "Error in %s event: row application failed. %s",
get_type_str(), get_type_str(),
thd->net.last_error ? thd->net.last_error : ""); thd->net.last_error ? thd->net.last_error : "");
thd->query_error= 1; thd->is_slave_error= 1;
break; break;
} }
@ -6221,7 +6221,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
*/ */
thd->reset_current_stmt_binlog_row_based(); thd->reset_current_stmt_binlog_row_based();
const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error); const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error);
thd->query_error= 1; thd->is_slave_error= 1;
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@ -6519,9 +6519,15 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
m_dblen(m_dbnam ? tbl->s->db.length : 0), m_dblen(m_dbnam ? tbl->s->db.length : 0),
m_tblnam(tbl->s->table_name.str), m_tblnam(tbl->s->table_name.str),
m_tbllen(tbl->s->table_name.length), m_tbllen(tbl->s->table_name.length),
m_colcnt(tbl->s->fields), m_field_metadata(0), m_colcnt(tbl->s->fields),
m_field_metadata_size(0), m_memory(NULL), m_meta_memory(NULL), m_data_size(0), m_memory(NULL),
m_table_id(tid), m_null_bits(0), m_flags(flags) m_table_id(tid),
m_flags(flags),
m_data_size(0),
m_field_metadata(0),
m_field_metadata_size(0),
m_null_bits(0),
m_meta_memory(NULL)
{ {
DBUG_ASSERT(m_table_id != ~0UL); DBUG_ASSERT(m_table_id != ~0UL);
/* /*
@ -6798,7 +6804,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
TABLE_LIST *tmp_table_list= table_list; TABLE_LIST *tmp_table_list= table_list;
if ((error= open_tables(thd, &tmp_table_list, &count, 0))) if ((error= open_tables(thd, &tmp_table_list, &count, 0)))
{ {
if (thd->query_error || thd->is_fatal_error) if (thd->is_slave_error || thd->is_fatal_error)
{ {
/* /*
Error reporting borrowed from Query_log_event with many excessive Error reporting borrowed from Query_log_event with many excessive
@ -6810,7 +6816,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
(actual_error ? thd->net.last_error : (actual_error ? thd->net.last_error :
"unexpected success or fatal error"), "unexpected success or fatal error"),
table_list->db, table_list->table_name); table_list->db, table_list->table_name);
thd->query_error= 1; thd->is_slave_error= 1;
} }
goto err; goto err;
} }

View File

@ -68,7 +68,7 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli
{ {
if (!need_reopen) if (!need_reopen)
{ {
if (thd->query_error || thd->is_fatal_error) if (thd->is_slave_error || thd->is_fatal_error)
{ {
/* /*
Error reporting borrowed from Query_log_event with many excessive Error reporting borrowed from Query_log_event with many excessive
@ -112,7 +112,7 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli
uint tables_count= rli->tables_to_lock_count; uint tables_count= rli->tables_to_lock_count;
if ((error= open_tables(thd, &tables, &tables_count, 0))) if ((error= open_tables(thd, &tables, &tables_count, 0)))
{ {
if (thd->query_error || thd->is_fatal_error) if (thd->is_slave_error || thd->is_fatal_error)
{ {
/* /*
Error reporting borrowed from Query_log_event with many excessive Error reporting borrowed from Query_log_event with many excessive
@ -123,7 +123,7 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli
"Error '%s' on reopening tables", "Error '%s' on reopening tables",
(actual_error ? thd->net.last_error : (actual_error ? thd->net.last_error :
"unexpected success or fatal error")); "unexpected success or fatal error"));
thd->query_error= 1; thd->is_slave_error= 1;
} }
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
DBUG_RETURN(error); DBUG_RETURN(error);
@ -146,7 +146,7 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli
{ {
mysql_unlock_tables(thd, thd->lock); mysql_unlock_tables(thd, thd->lock);
thd->lock= 0; thd->lock= 0;
thd->query_error= 1; thd->is_slave_error= 1;
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
DBUG_RETURN(Rows_log_event::ERR_BAD_TABLE_DEF); DBUG_RETURN(Rows_log_event::ERR_BAD_TABLE_DEF);
} }
@ -255,7 +255,7 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli
"Error in %s event: row application failed. %s", "Error in %s event: row application failed. %s",
ev->get_type_str(), ev->get_type_str(),
thd->net.last_error ? thd->net.last_error : ""); thd->net.last_error ? thd->net.last_error : "");
thd->query_error= 1; thd->is_slave_error= 1;
break; break;
} }
@ -300,7 +300,7 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli
*/ */
thd->reset_current_stmt_binlog_row_based(); thd->reset_current_stmt_binlog_row_based();
const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error); const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error);
thd->query_error= 1; thd->is_slave_error= 1;
DBUG_RETURN(error); DBUG_RETURN(error);
} }

View File

@ -695,7 +695,7 @@ extern my_decimal decimal_zero;
void free_items(Item *item); void free_items(Item *item);
void cleanup_items(Item *item); void cleanup_items(Item *item);
class THD; class THD;
void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0); void close_thread_tables(THD *thd);
bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables); bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables);
bool check_single_table_access(THD *thd, ulong privilege, bool check_single_table_access(THD *thd, ulong privilege,
TABLE_LIST *tables, bool no_errors); TABLE_LIST *tables, bool no_errors);
@ -936,7 +936,6 @@ bool init_new_connection_handler_thread();
void reset_mqh(LEX_USER *lu, bool get_them); void reset_mqh(LEX_USER *lu, bool get_them);
bool check_mqh(THD *thd, uint check_command); bool check_mqh(THD *thd, uint check_command);
void time_out_user_resource_limits(THD *thd, USER_CONN *uc); void time_out_user_resource_limits(THD *thd, USER_CONN *uc);
int check_for_max_user_connections(THD *thd, USER_CONN *uc);
void decrease_user_connections(USER_CONN *uc); void decrease_user_connections(USER_CONN *uc);
void thd_init_client_charset(THD *thd, uint cs_number); void thd_init_client_charset(THD *thd, uint cs_number);
bool setup_connection_thread_globals(THD *thd); bool setup_connection_thread_globals(THD *thd);
@ -1436,7 +1435,7 @@ TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
bool check_alias); bool check_alias);
TABLE *find_temporary_table(THD *thd, const char *db, const char *table_name); TABLE *find_temporary_table(THD *thd, const char *db, const char *table_name);
TABLE *find_temporary_table(THD *thd, TABLE_LIST *table_list); TABLE *find_temporary_table(THD *thd, TABLE_LIST *table_list);
bool close_temporary_table(THD *thd, TABLE_LIST *table_list); int drop_temporary_table(THD *thd, TABLE_LIST *table_list);
void close_temporary_table(THD *thd, TABLE *table, bool free_share, void close_temporary_table(THD *thd, TABLE *table, bool free_share,
bool delete_table); bool delete_table);
void close_temporary(TABLE *table, bool free_share, bool delete_table); void close_temporary(TABLE *table, bool free_share, bool delete_table);

View File

@ -2584,7 +2584,7 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
TODO: There are two exceptions mechanism (THD and sp_rcontext), TODO: There are two exceptions mechanism (THD and sp_rcontext),
this could be improved by having a common stack of handlers. this could be improved by having a common stack of handlers.
*/ */
if (thd->handle_error(error, if (thd->handle_error(error, str,
MYSQL_ERROR::WARN_LEVEL_ERROR)) MYSQL_ERROR::WARN_LEVEL_ERROR))
DBUG_RETURN(0); DBUG_RETURN(0);
@ -2594,7 +2594,7 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
thd->query_error= 1; // needed to catch query errors during replication thd->is_slave_error= 1; // needed to catch query errors during replication
if (!thd->no_warnings_for_error) if (!thd->no_warnings_for_error)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str); push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
@ -4303,6 +4303,7 @@ void create_thread_to_handle_connection(THD *thd)
} }
else else
{ {
char error_message_buff[MYSQL_ERRMSG_SIZE];
/* Create new thread to handle connection */ /* Create new thread to handle connection */
int error; int error;
thread_created++; thread_created++;
@ -4321,7 +4322,10 @@ void create_thread_to_handle_connection(THD *thd)
thd->killed= THD::KILL_CONNECTION; // Safety thd->killed= THD::KILL_CONNECTION; // Safety
(void) pthread_mutex_unlock(&LOCK_thread_count); (void) pthread_mutex_unlock(&LOCK_thread_count);
statistic_increment(aborted_connects,&LOCK_status); statistic_increment(aborted_connects,&LOCK_status);
net_printf_error(thd, ER_CANT_CREATE_THREAD, error); /* Can't use my_error() since store_globals has not been called. */
my_snprintf(error_message_buff, sizeof(error_message_buff),
ER(ER_CANT_CREATE_THREAD), error);
net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff);
(void) pthread_mutex_lock(&LOCK_thread_count); (void) pthread_mutex_lock(&LOCK_thread_count);
close_connection(thd,0,0); close_connection(thd,0,0);
delete thd; delete thd;

View File

@ -58,7 +58,7 @@ bool Protocol_binary::net_store_data(const uchar *from, size_t length)
Design note: Design note:
net_printf_error and net_send_error are low-level functions net_send_error is a low-level functions
that shall be used only when a new connection is being that shall be used only when a new connection is being
established or at server startup. established or at server startup.
For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
@ -84,7 +84,7 @@ void net_send_error(THD *thd, uint sql_errno, const char *err)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
thd->query_error= 1; // needed to catch query errors during replication thd->is_slave_error= 1; // needed to catch query errors during replication
if (!err) if (!err)
{ {
if (sql_errno) if (sql_errno)
@ -120,124 +120,6 @@ void net_send_error(THD *thd, uint sql_errno, const char *err)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/*
Write error package and flush to client
It's a little too low level, but I don't want to use another buffer for
this
Design note:
net_printf_error and net_send_error are low-level functions
that shall be used only when a new connection is being
established or at server startup.
For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
critical that every error that can be intercepted is issued in one
place only, my_message_sql.
*/
void
net_printf_error(THD *thd, uint errcode, ...)
{
va_list args;
uint length,offset;
const char *format;
#ifndef EMBEDDED_LIBRARY
const char *text_pos;
int head_length= NET_HEADER_SIZE;
#else
char text_pos[1024];
#endif
NET *net= &thd->net;
DBUG_ENTER("net_printf_error");
DBUG_PRINT("enter",("message: %u",errcode));
DBUG_ASSERT(!thd->spcont);
if (net && net->no_send_error)
{
thd->clear_error();
thd->is_fatal_error= 0; // Error message is given
DBUG_PRINT("info", ("sending error messages prohibited"));
DBUG_VOID_RETURN;
}
thd->query_error= 1; // needed to catch query errors during replication
#ifndef EMBEDDED_LIBRARY
query_cache_abort(net); // Safety
#endif
va_start(args,errcode);
/*
The following is needed to make net_printf_error() work with 0 argument
for errorcode and use the argument after that as the format string. This
is useful for rare errors that are not worth the hassle to put in
errmsg.sys, but at the same time, the message is not fixed text
*/
if (errcode)
format= ER(errcode);
else
{
format=va_arg(args,char*);
errcode= ER_UNKNOWN_ERROR;
}
offset= (net->return_errno ?
((thd->client_capabilities & CLIENT_PROTOCOL_41) ?
2+SQLSTATE_LENGTH+1 : 2) : 0);
#ifndef EMBEDDED_LIBRARY
text_pos=(char*) net->buff + head_length + offset + 1;
length= (uint) ((char*)net->buff_end - text_pos);
#else
length=sizeof(text_pos)-1;
#endif
length=my_vsnprintf(my_const_cast(char*) (text_pos),
min(length, sizeof(net->last_error)),
format,args);
va_end(args);
/* Replication slave relies on net->last_* to see if there was error */
net->last_errno= errcode;
strmake(net->last_error, text_pos, sizeof(net->last_error)-1);
#ifndef EMBEDDED_LIBRARY
if (net->vio == 0)
{
if (thd->bootstrap)
{
/*
In bootstrap it's ok to print on stderr
This may also happen when we get an error from a slave thread
*/
fprintf(stderr,"ERROR: %d %s\n",errcode,text_pos);
thd->fatal_error();
}
DBUG_VOID_RETURN;
}
int3store(net->buff,length+1+offset);
net->buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
net->buff[head_length]=(uchar) 255; // Error package
if (offset)
{
uchar *pos= net->buff+head_length+1;
int2store(pos, errcode);
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{
pos[2]= '#'; /* To make the protocol backward compatible */
memcpy(pos+3, mysql_errno_to_sqlstate(errcode), SQLSTATE_LENGTH);
}
}
VOID(net_real_write(net, net->buff, length+head_length+1+offset));
#else
net->last_errno= errcode;
strmake(net->last_error, text_pos, length);
strmake(net->sqlstate, mysql_errno_to_sqlstate(errcode), SQLSTATE_LENGTH);
#endif
if (thd->killed != THD::KILL_CONNECTION)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, errcode,
text_pos ? text_pos : ER(errcode));
thd->is_fatal_error=0; // Error message is given
DBUG_VOID_RETURN;
}
/* /*
Return ok to the client. Return ok to the client.

View File

@ -172,7 +172,6 @@ public:
}; };
void send_warning(THD *thd, uint sql_errno, const char *err=0); void send_warning(THD *thd, uint sql_errno, const char *err=0);
void net_printf_error(THD *thd, uint sql_errno, ...);
void net_send_error(THD *thd, uint sql_errno=0, const char *err=0); void net_send_error(THD *thd, uint sql_errno=0, const char *err=0);
void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L, void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L,
const char *info=0); const char *info=0);

View File

@ -3059,7 +3059,7 @@ int sql_set_variables(THD *thd, List<set_var_base> *var_list)
if ((error= var->check(thd))) if ((error= var->check(thd)))
goto err; goto err;
} }
if (!(error= test(thd->net.report_error))) if (!(error= test(thd->is_error())))
{ {
it.rewind(); it.rewind();
while ((var= it++)) while ((var= it++))

View File

@ -980,7 +980,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
DBUG_RETURN(1); DBUG_RETURN(1);
} }
thd->query= query; thd->query= query;
thd->query_error = 0; thd->is_slave_error = 0;
thd->net.no_send_ok = 1; thd->net.no_send_ok = 1;
bzero((char*) &tables,sizeof(tables)); bzero((char*) &tables,sizeof(tables));
@ -1009,7 +1009,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
thd->db_length= save_db_length; thd->db_length= save_db_length;
thd->options = save_options; thd->options = save_options;
if (thd->query_error) if (thd->is_slave_error)
goto err; // mysql_parse took care of the error send goto err; // mysql_parse took care of the error send
thd_proc_info(thd, "Opening master dump table"); thd_proc_info(thd, "Opening master dump table");
@ -2353,7 +2353,7 @@ err:
change_rpl_status(RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE); change_rpl_status(RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE);
DBUG_ASSERT(thd->net.buff != 0); DBUG_ASSERT(thd->net.buff != 0);
net_end(&thd->net); // destructor will not free it, because net.vio is 0 net_end(&thd->net); // destructor will not free it, because net.vio is 0
close_thread_tables(thd, 0); close_thread_tables(thd);
pthread_mutex_lock(&LOCK_thread_count); pthread_mutex_lock(&LOCK_thread_count);
THD_CHECK_SENTRY(thd); THD_CHECK_SENTRY(thd);
delete thd; delete thd;
@ -2501,7 +2501,7 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
if (sys_init_slave.value_length) if (sys_init_slave.value_length)
{ {
execute_init_command(thd, &sys_init_slave, &LOCK_sys_init_slave); execute_init_command(thd, &sys_init_slave, &LOCK_sys_init_slave);
if (thd->query_error) if (thd->is_slave_error)
{ {
sql_print_error("\ sql_print_error("\
Slave SQL thread aborted. Can't execute init_slave query"); Slave SQL thread aborted. Can't execute init_slave query");

View File

@ -1866,7 +1866,7 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
an error with it's return value without calling my_error(), we an error with it's return value without calling my_error(), we
set the generic "mysql.proc table corrupt" error here. set the generic "mysql.proc table corrupt" error here.
*/ */
if (!thd->net.report_error) if (! thd->is_error())
{ {
/* /*
SP allows full NAME_LEN chars thus he have to allocate enough SP allows full NAME_LEN chars thus he have to allocate enough

View File

@ -370,7 +370,7 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
thd->abort_on_warning= save_abort_on_warning; thd->abort_on_warning= save_abort_on_warning;
thd->transaction.stmt.modified_non_trans_table= save_stmt_modified_non_trans_table; thd->transaction.stmt.modified_non_trans_table= save_stmt_modified_non_trans_table;
if (thd->net.report_error) if (thd->is_error())
{ {
/* Return error status if something went wrong. */ /* Return error status if something went wrong. */
err_status= TRUE; err_status= TRUE;
@ -1108,7 +1108,7 @@ sp_head::execute(THD *thd)
if ((ctx= thd->spcont)) if ((ctx= thd->spcont))
ctx->clear_handler(); ctx->clear_handler();
thd->query_error= 0; thd->is_slave_error= 0;
old_arena= thd->stmt_arena; old_arena= thd->stmt_arena;
/* /*
@ -1275,9 +1275,9 @@ sp_head::execute(THD *thd)
state= EXECUTED; state= EXECUTED;
done: done:
DBUG_PRINT("info", ("err_status: %d killed: %d query_error: %d report_error: %d", DBUG_PRINT("info", ("err_status: %d killed: %d is_slave_error: %d report_error: %d",
err_status, thd->killed, thd->query_error, err_status, thd->killed, thd->is_slave_error,
thd->net.report_error)); thd->is_error()));
if (thd->killed) if (thd->killed)
err_status= TRUE; err_status= TRUE;
@ -1872,7 +1872,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
we'll leave it here. we'll leave it here.
*/ */
if (!thd->in_sub_stmt) if (!thd->in_sub_stmt)
close_thread_tables(thd, 0, 0); close_thread_tables(thd);
DBUG_PRINT("info",(" %.*s: eval args done", DBUG_PRINT("info",(" %.*s: eval args done",
(int) m_name.length, m_name.str)); (int) m_name.length, m_name.str));
@ -2673,7 +2673,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
cleanup_items() is called in sp_head::execute() cleanup_items() is called in sp_head::execute()
*/ */
DBUG_RETURN(res || thd->net.report_error); DBUG_RETURN(res || thd->is_error());
} }

View File

@ -428,7 +428,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
continue; continue;
} }
const char *password= get_field(&mem, table->field[2]); const char *password= get_field(thd->mem_root, table->field[2]);
uint password_len= password ? strlen(password) : 0; uint password_len= password ? strlen(password) : 0;
set_user_salt(&user, password, password_len); set_user_salt(&user, password, password_len);
if (user.salt_len == 0 && password_len != 0) if (user.salt_len == 0 && password_len != 0)
@ -495,7 +495,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
/* Starting from 4.0.2 we have more fields */ /* Starting from 4.0.2 we have more fields */
if (table->s->fields >= 31) if (table->s->fields >= 31)
{ {
char *ssl_type=get_field(&mem, table->field[next_field++]); char *ssl_type=get_field(thd->mem_root, table->field[next_field++]);
if (!ssl_type) if (!ssl_type)
user.ssl_type=SSL_TYPE_NONE; user.ssl_type=SSL_TYPE_NONE;
else if (!strcmp(ssl_type, "ANY")) else if (!strcmp(ssl_type, "ANY"))
@ -509,11 +509,11 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
user.x509_issuer= get_field(&mem, table->field[next_field++]); user.x509_issuer= get_field(&mem, table->field[next_field++]);
user.x509_subject= get_field(&mem, table->field[next_field++]); user.x509_subject= get_field(&mem, table->field[next_field++]);
char *ptr = get_field(&mem, table->field[next_field++]); char *ptr = get_field(thd->mem_root, table->field[next_field++]);
user.user_resource.questions=ptr ? atoi(ptr) : 0; user.user_resource.questions=ptr ? atoi(ptr) : 0;
ptr = get_field(&mem, table->field[next_field++]); ptr = get_field(thd->mem_root, table->field[next_field++]);
user.user_resource.updates=ptr ? atoi(ptr) : 0; user.user_resource.updates=ptr ? atoi(ptr) : 0;
ptr = get_field(&mem, table->field[next_field++]); ptr = get_field(thd->mem_root, table->field[next_field++]);
user.user_resource.conn_per_hour= ptr ? atoi(ptr) : 0; user.user_resource.conn_per_hour= ptr ? atoi(ptr) : 0;
if (user.user_resource.questions || user.user_resource.updates || if (user.user_resource.questions || user.user_resource.updates ||
user.user_resource.conn_per_hour) user.user_resource.conn_per_hour)
@ -522,7 +522,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
if (table->s->fields >= 36) if (table->s->fields >= 36)
{ {
/* Starting from 5.0.3 we have max_user_connections field */ /* Starting from 5.0.3 we have max_user_connections field */
ptr= get_field(&mem, table->field[next_field++]); ptr= get_field(thd->mem_root, table->field[next_field++]);
user.user_resource.user_conn= ptr ? atoi(ptr) : 0; user.user_resource.user_conn= ptr ? atoi(ptr) : 0;
} }
else else
@ -5050,6 +5050,7 @@ static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop,
uchar user_key[MAX_KEY_LENGTH]; uchar user_key[MAX_KEY_LENGTH];
uint key_prefix_length; uint key_prefix_length;
DBUG_ENTER("handle_grant_table"); DBUG_ENTER("handle_grant_table");
THD *thd= current_thd;
table->use_all_columns(); table->use_all_columns();
if (! table_no) // mysql.user table if (! table_no) // mysql.user table
@ -5118,17 +5119,18 @@ static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop,
DBUG_PRINT("info",("scan error: %d", error)); DBUG_PRINT("info",("scan error: %d", error));
continue; continue;
} }
if (! (host= get_field(&mem, host_field))) if (! (host= get_field(thd->mem_root, host_field)))
host= ""; host= "";
if (! (user= get_field(&mem, user_field))) if (! (user= get_field(thd->mem_root, user_field)))
user= ""; user= "";
#ifdef EXTRA_DEBUG #ifdef EXTRA_DEBUG
DBUG_PRINT("loop",("scan fields: '%s'@'%s' '%s' '%s' '%s'", DBUG_PRINT("loop",("scan fields: '%s'@'%s' '%s' '%s' '%s'",
user, host, user, host,
get_field(&mem, table->field[1]) /*db*/, get_field(thd->mem_root, table->field[1]) /*db*/,
get_field(&mem, table->field[3]) /*table*/, get_field(thd->mem_root, table->field[3]) /*table*/,
get_field(&mem, table->field[4]) /*column*/)); get_field(thd->mem_root,
table->field[4]) /*column*/));
#endif #endif
if (strcmp(user_str, user) || if (strcmp(user_str, user) ||
my_strcasecmp(system_charset_info, host_str, host)) my_strcasecmp(system_charset_info, host_str, host))

View File

@ -44,7 +44,7 @@ public:
virtual ~Prelock_error_handler() {} virtual ~Prelock_error_handler() {}
virtual bool handle_error(uint sql_errno, virtual bool handle_error(uint sql_errno, const char *message,
MYSQL_ERROR::enum_warning_level level, MYSQL_ERROR::enum_warning_level level,
THD *thd); THD *thd);
@ -58,6 +58,7 @@ private:
bool bool
Prelock_error_handler::handle_error(uint sql_errno, Prelock_error_handler::handle_error(uint sql_errno,
const char * /* message */,
MYSQL_ERROR::enum_warning_level /* level */, MYSQL_ERROR::enum_warning_level /* level */,
THD * /* thd */) THD * /* thd */)
{ {
@ -1054,6 +1055,29 @@ bool close_cached_connection_tables(THD *thd, bool if_wait_for_refresh,
} }
/**
Mark all temporary tables which were used by the current statement or
substatement as free for reuse, but only if the query_id can be cleared.
@param thd thread context
@remark For temp tables associated with a open SQL HANDLER the query_id
is not reset until the HANDLER is closed.
*/
static void mark_temp_tables_as_free_for_reuse(THD *thd)
{
for (TABLE *table= thd->temporary_tables ; table ; table= table->next)
{
if ((table->query_id == thd->query_id) && ! table->open_by_handler)
{
table->query_id= 0;
table->file->ha_reset();
}
}
}
/* /*
Mark all tables in the list which were used by current substatement Mark all tables in the list which were used by current substatement
as free for reuse. as free for reuse.
@ -1090,6 +1114,42 @@ static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table)
} }
/**
Auxiliary function to close all tables in the open_tables list.
@param thd Thread context.
@remark It should not ordinarily be called directly.
*/
static void close_open_tables(THD *thd)
{
bool found_old_table= 0;
safe_mutex_assert_not_owner(&LOCK_open);
VOID(pthread_mutex_lock(&LOCK_open));
DBUG_PRINT("info", ("thd->open_tables: 0x%lx", (long) thd->open_tables));
while (thd->open_tables)
found_old_table|= close_thread_table(thd, &thd->open_tables);
thd->some_tables_deleted= 0;
/* Free tables to hold down open files */
while (open_cache.records > table_cache_size && unused_tables)
VOID(hash_delete(&open_cache,(uchar*) unused_tables)); /* purecov: tested */
check_unused();
if (found_old_table)
{
/* Tell threads waiting for refresh that something has happened */
broadcast_refresh();
}
VOID(pthread_mutex_unlock(&LOCK_open));
}
/* /*
Close all tables used by the current substatement, or all tables Close all tables used by the current substatement, or all tables
used by this thread if we are on the upper level. used by this thread if we are on the upper level.
@ -1097,26 +1157,19 @@ static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table)
SYNOPSIS SYNOPSIS
close_thread_tables() close_thread_tables()
thd Thread handler thd Thread handler
lock_in_use Set to 1 (0 = default) if caller has a lock on
LOCK_open
skip_derived Set to 1 (0 = default) if we should not free derived
tables.
stopper When closing tables from thd->open_tables(->next)*,
don't close/remove tables starting from stopper.
IMPLEMENTATION IMPLEMENTATION
Unlocks tables and frees derived tables. Unlocks tables and frees derived tables.
Put all normal tables used by thread in free list. Put all normal tables used by thread in free list.
When in prelocked mode it will only close/mark as free for reuse It will only close/mark as free for reuse tables opened by this
tables opened by this substatement, it will also check if we are substatement, it will also check if we are closing tables after
closing tables after execution of complete query (i.e. we are on execution of complete query (i.e. we are on upper level) and will
upper level) and will leave prelocked mode if needed. leave prelocked mode if needed.
*/ */
void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived) void close_thread_tables(THD *thd)
{ {
bool found_old_table;
prelocked_mode_type prelocked_mode= thd->prelocked_mode; prelocked_mode_type prelocked_mode= thd->prelocked_mode;
DBUG_ENTER("close_thread_tables"); DBUG_ENTER("close_thread_tables");
@ -1131,7 +1184,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
derived tables with (sub-)statement instead of thread and destroy derived tables with (sub-)statement instead of thread and destroy
them at the end of its execution. them at the end of its execution.
*/ */
if (thd->derived_tables && !skip_derived) if (thd->derived_tables)
{ {
TABLE *table, *next; TABLE *table, *next;
/* /*
@ -1146,13 +1199,10 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
thd->derived_tables= 0; thd->derived_tables= 0;
} }
if (prelocked_mode) /*
{ Mark all temporary tables used by this statement as free for reuse.
/* */
Mark all temporary tables used by this substatement as free for reuse. mark_temp_tables_as_free_for_reuse(thd);
*/
mark_used_tables_as_free_for_reuse(thd, thd->temporary_tables);
}
if (thd->locked_tables || prelocked_mode) if (thd->locked_tables || prelocked_mode)
{ {
@ -1216,28 +1266,8 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
if (!thd->active_transaction()) if (!thd->active_transaction())
thd->transaction.xid_state.xid.null(); thd->transaction.xid_state.xid.null();
if (!lock_in_use) if (thd->open_tables)
VOID(pthread_mutex_lock(&LOCK_open)); close_open_tables(thd);
DBUG_PRINT("info", ("thd->open_tables: 0x%lx", (long) thd->open_tables));
found_old_table= 0;
while (thd->open_tables)
found_old_table|= close_thread_table(thd, &thd->open_tables);
thd->some_tables_deleted=0;
/* Free tables to hold down open files */
while (open_cache.records > table_cache_size && unused_tables)
VOID(hash_delete(&open_cache,(uchar*) unused_tables)); /* purecov: tested */
check_unused();
if (found_old_table)
{
/* Tell threads waiting for refresh that something has happened */
broadcast_refresh();
}
if (!lock_in_use)
VOID(pthread_mutex_unlock(&LOCK_open));
/* VOID(pthread_sigmask(SIG_SETMASK,&thd->signals,NULL)); */
if (prelocked_mode == PRELOCKED) if (prelocked_mode == PRELOCKED)
{ {
@ -1674,6 +1704,7 @@ TABLE *find_temporary_table(THD *thd, TABLE_LIST *table_list)
Try to locate the table in the list of thd->temporary_tables. Try to locate the table in the list of thd->temporary_tables.
If the table is found: If the table is found:
- if the table is being used by some outer statement, fail.
- if the table is in thd->locked_tables, unlock it and - if the table is in thd->locked_tables, unlock it and
remove it from the list of locked tables. Currently only transactional remove it from the list of locked tables. Currently only transactional
temporary tables are present in the locked_tables list. temporary tables are present in the locked_tables list.
@ -1688,24 +1719,34 @@ TABLE *find_temporary_table(THD *thd, TABLE_LIST *table_list)
thd->temporary_tables list, it's impossible to tell here whether thd->temporary_tables list, it's impossible to tell here whether
we're dealing with an internal or a user temporary table. we're dealing with an internal or a user temporary table.
@retval TRUE the table was not found in the list of temporary tables @retval 0 the table was found and dropped successfully.
of this thread @retval 1 the table was not found in the list of temporary tables
@retval FALSE the table was found and dropped successfully. of this thread
@retval -1 the table is in use by a outer query
*/ */
bool close_temporary_table(THD *thd, TABLE_LIST *table_list) int drop_temporary_table(THD *thd, TABLE_LIST *table_list)
{ {
TABLE *table; TABLE *table;
DBUG_ENTER("drop_temporary_table");
if (!(table= find_temporary_table(thd, table_list))) if (!(table= find_temporary_table(thd, table_list)))
return 1; DBUG_RETURN(1);
/* Table might be in use by some outer statement. */
if (table->query_id && table->query_id != thd->query_id)
{
my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
DBUG_RETURN(-1);
}
/* /*
If LOCK TABLES list is not empty and contains this table, If LOCK TABLES list is not empty and contains this table,
unlock the table and remove the table from this list. unlock the table and remove the table from this list.
*/ */
mysql_lock_remove(thd, thd->locked_tables, table, FALSE); mysql_lock_remove(thd, thd->locked_tables, table, FALSE);
close_temporary_table(thd, table, 1, 1); close_temporary_table(thd, table, 1, 1);
return 0; DBUG_RETURN(0);
} }
/* /*
@ -2284,8 +2325,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
is always represented by only one TABLE object in THD, and is always represented by only one TABLE object in THD, and
it can not be cloned. Emit an error for an unsupported behaviour. it can not be cloned. Emit an error for an unsupported behaviour.
*/ */
if (table->query_id == thd->query_id || if (table->query_id)
thd->prelocked_mode && table->query_id)
{ {
DBUG_PRINT("error", DBUG_PRINT("error",
("query_id: %lu server_id: %u pseudo_thread_id: %lu", ("query_id: %lu server_id: %u pseudo_thread_id: %lu",
@ -2295,7 +2335,6 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
table->query_id= thd->query_id; table->query_id= thd->query_id;
table->clear_query_id= 1;
thd->thread_specific_used= TRUE; thd->thread_specific_used= TRUE;
DBUG_PRINT("info",("Using temporary table")); DBUG_PRINT("info",("Using temporary table"));
goto reset; goto reset;
@ -4305,7 +4344,6 @@ void close_tables_for_reopen(THD *thd, TABLE_LIST **tables)
sp_remove_not_own_routines(thd->lex); sp_remove_not_own_routines(thd->lex);
for (TABLE_LIST *tmp= *tables; tmp; tmp= tmp->next_global) for (TABLE_LIST *tmp= *tables; tmp; tmp= tmp->next_global)
tmp->table= 0; tmp->table= 0;
mark_used_tables_as_free_for_reuse(thd, thd->temporary_tables);
close_thread_tables(thd); close_thread_tables(thd);
} }
@ -6260,7 +6298,7 @@ bool setup_fields(THD *thd, Item **ref_pointer_array,
thd->lex->allow_sum_func= save_allow_sum_func; thd->lex->allow_sum_func= save_allow_sum_func;
thd->mark_used_columns= save_mark_used_columns; thd->mark_used_columns= save_mark_used_columns;
DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
DBUG_RETURN(test(thd->net.report_error)); DBUG_RETURN(test(thd->is_error()));
} }
@ -6804,7 +6842,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
select_lex->conds_processed_with_permanent_arena= 1; select_lex->conds_processed_with_permanent_arena= 1;
} }
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup; thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
DBUG_RETURN(test(thd->net.report_error)); DBUG_RETURN(test(thd->is_error()));
err_no_arena: err_no_arena:
select_lex->is_item_list_lookup= save_is_item_list_lookup; select_lex->is_item_list_lookup= save_is_item_list_lookup;
@ -6886,7 +6924,7 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
goto err; goto err;
} }
} }
DBUG_RETURN(thd->net.report_error); DBUG_RETURN(thd->is_error());
err: err:
if (table) if (table)
table->auto_increment_field_not_null= FALSE; table->auto_increment_field_not_null= FALSE;
@ -6971,7 +7009,7 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors)
table= (*ptr)->table; table= (*ptr)->table;
table->auto_increment_field_not_null= FALSE; table->auto_increment_field_not_null= FALSE;
} }
while ((field = *ptr++) && !thd->net.report_error) while ((field = *ptr++) && ! thd->is_error())
{ {
value=v++; value=v++;
table= field->table; table= field->table;
@ -6980,7 +7018,7 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors)
if (value->save_in_field(field, 0) < 0) if (value->save_in_field(field, 0) < 0)
goto err; goto err;
} }
DBUG_RETURN(thd->net.report_error); DBUG_RETURN(thd->is_error());
err: err:
if (table) if (table)
@ -7390,7 +7428,7 @@ open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias,
else else
{ {
/* only VIEWs are supported now */ /* only VIEWs are supported now */
my_error(ER_FRM_UNKNOWN_TYPE, MYF(0), share->path, parser->type()->str); my_error(ER_FRM_UNKNOWN_TYPE, MYF(0), share->path.str, parser->type()->str);
goto err; goto err;
} }
DBUG_RETURN(0); DBUG_RETURN(0);

View File

@ -37,6 +37,9 @@ void mysql_client_binlog_statement(THD* thd)
thd->lex->comment.length : 2048), thd->lex->comment.length : 2048),
thd->lex->comment.str)); thd->lex->comment.str));
if (check_global_access(thd, SUPER_ACL))
DBUG_VOID_RETURN;
/* /*
Temporarily turn off send_ok, since different events handle this Temporarily turn off send_ok, since different events handle this
differently differently

View File

@ -402,7 +402,7 @@ THD::THD()
count_cuted_fields= CHECK_FIELD_IGNORE; count_cuted_fields= CHECK_FIELD_IGNORE;
killed= NOT_KILLED; killed= NOT_KILLED;
col_access=0; col_access=0;
query_error= thread_specific_used= FALSE; is_slave_error= thread_specific_used= FALSE;
hash_clear(&handler_tables_hash); hash_clear(&handler_tables_hash);
tmp_table=0; tmp_table=0;
used_tables=0; used_tables=0;
@ -508,12 +508,12 @@ void THD::push_internal_handler(Internal_error_handler *handler)
} }
bool THD::handle_error(uint sql_errno, bool THD::handle_error(uint sql_errno, const char *message,
MYSQL_ERROR::enum_warning_level level) MYSQL_ERROR::enum_warning_level level)
{ {
if (m_internal_handler) if (m_internal_handler)
{ {
return m_internal_handler->handle_error(sql_errno, level, this); return m_internal_handler->handle_error(sql_errno, message, level, this);
} }
return FALSE; // 'FALSE', as per coding style return FALSE; // 'FALSE', as per coding style
@ -1315,23 +1315,26 @@ bool select_send::send_fields(List<Item> &list, uint flags)
{ {
bool res; bool res;
if (!(res= thd->protocol->send_fields(&list, flags))) if (!(res= thd->protocol->send_fields(&list, flags)))
status= 1; is_result_set_started= 1;
return res; return res;
} }
void select_send::abort() void select_send::abort()
{ {
DBUG_ENTER("select_send::abort"); DBUG_ENTER("select_send::abort");
if (status && thd->spcont && if (is_result_set_started && thd->spcont &&
thd->spcont->find_handler(thd, thd->net.last_errno, thd->spcont->find_handler(thd, thd->net.last_errno,
MYSQL_ERROR::WARN_LEVEL_ERROR)) MYSQL_ERROR::WARN_LEVEL_ERROR))
{ {
/* /*
Executing stored procedure without a handler. We're executing a stored procedure, have an open result
Here we should actually send an error to the client, set, an SQL exception conditiona and a handler for it.
but as an error will break a multiple result set, the only thing we In this situation we must abort the current statement,
can do for now is to nicely end the current data set and remembering silence the error and start executing the continue/exit
the error so that the calling routine will abort handler.
Before aborting the statement, let's end the open result set, as
otherwise the client will hang due to the violation of the
client/server protocol.
*/ */
thd->net.report_error= 0; thd->net.report_error= 0;
send_eof(); send_eof();
@ -1341,6 +1344,17 @@ void select_send::abort()
} }
/**
Cleanup an instance of this class for re-use
at next execution of a prepared statement/
stored procedure statement.
*/
void select_send::cleanup()
{
is_result_set_started= FALSE;
}
/* Send data to client. Returns 0 if ok */ /* Send data to client. Returns 0 if ok */
bool select_send::send_data(List<Item> &items) bool select_send::send_data(List<Item> &items)
@ -1378,7 +1392,7 @@ bool select_send::send_data(List<Item> &items)
thd->sent_row_count++; thd->sent_row_count++;
if (!thd->vio_ok()) if (!thd->vio_ok())
DBUG_RETURN(0); DBUG_RETURN(0);
if (!thd->net.report_error) if (! thd->is_error())
DBUG_RETURN(protocol->write()); DBUG_RETURN(protocol->write());
protocol->remove_last_row(); protocol->remove_last_row();
DBUG_RETURN(1); DBUG_RETURN(1);
@ -1399,10 +1413,10 @@ bool select_send::send_eof()
mysql_unlock_tables(thd, thd->lock); mysql_unlock_tables(thd, thd->lock);
thd->lock=0; thd->lock=0;
} }
if (!thd->net.report_error) if (! thd->is_error())
{ {
::send_eof(thd); ::send_eof(thd);
status= 0; is_result_set_started= 0;
return 0; return 0;
} }
else else
@ -2414,6 +2428,7 @@ void Security_context::init()
host= user= priv_user= ip= 0; host= user= priv_user= ip= 0;
host_or_ip= "connecting host"; host_or_ip= "connecting host";
priv_host[0]= '\0'; priv_host[0]= '\0';
master_access= 0;
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
db_access= NO_ACCESS; db_access= NO_ACCESS;
#endif #endif

View File

@ -970,6 +970,7 @@ public:
@return true if the error is handled @return true if the error is handled
*/ */
virtual bool handle_error(uint sql_errno, virtual bool handle_error(uint sql_errno,
const char *message,
MYSQL_ERROR::enum_warning_level level, MYSQL_ERROR::enum_warning_level level,
THD *thd) = 0; THD *thd) = 0;
}; };
@ -1474,7 +1475,14 @@ public:
/* for IS NULL => = last_insert_id() fix in remove_eq_conds() */ /* for IS NULL => = last_insert_id() fix in remove_eq_conds() */
bool substitute_null_with_insert_id; bool substitute_null_with_insert_id;
bool in_lock_tables; bool in_lock_tables;
bool query_error, bootstrap, cleanup_done; /**
True if a slave error. Causes the slave to stop. Not the same
as the statement execution error (is_error()), since
a statement may be expected to return an error, e.g. because
it returned an error on master, and this is OK on the slave.
*/
bool is_slave_error;
bool bootstrap, cleanup_done;
/** is set if some thread specific value(s) used in a statement. */ /** is set if some thread specific value(s) used in a statement. */
bool thread_specific_used; bool thread_specific_used;
@ -1703,7 +1711,7 @@ public:
net.last_error[0]= 0; net.last_error[0]= 0;
net.last_errno= 0; net.last_errno= 0;
net.report_error= 0; net.report_error= 0;
query_error= 0; is_slave_error= 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
inline bool vio_ok() const { return net.vio != 0; } inline bool vio_ok() const { return net.vio != 0; }
@ -1717,6 +1725,20 @@ public:
net.report_error= 1; net.report_error= 1;
DBUG_PRINT("error",("Fatal error set")); DBUG_PRINT("error",("Fatal error set"));
} }
/**
TRUE if there is an error in the error stack.
Please use this method instead of direct access to
net.report_error.
If TRUE, the current (sub)-statement should be aborted.
The main difference between this member and is_fatal_error
is that a fatal error can not be handled by a stored
procedure continue handler, whereas a normal error can.
To raise this flag, use my_error().
*/
inline bool is_error() const { return net.report_error; }
inline CHARSET_INFO *charset() { return variables.character_set_client; } inline CHARSET_INFO *charset() { return variables.character_set_client; }
void update_charset(); void update_charset();
@ -1910,7 +1932,7 @@ public:
@param level the error level @param level the error level
@return true if the error is handled @return true if the error is handled
*/ */
virtual bool handle_error(uint sql_errno, virtual bool handle_error(uint sql_errno, const char *message,
MYSQL_ERROR::enum_warning_level level); MYSQL_ERROR::enum_warning_level level);
/** /**
@ -2037,14 +2059,20 @@ public:
class select_send :public select_result { class select_send :public select_result {
int status; /**
True if we have sent result set metadata to the client.
In this case the client always expects us to end the result
set with an eof or error packet
*/
bool is_result_set_started;
public: public:
select_send() :status(0) {} select_send() :is_result_set_started(FALSE) {}
bool send_fields(List<Item> &list, uint flags); bool send_fields(List<Item> &list, uint flags);
bool send_data(List<Item> &items); bool send_data(List<Item> &items);
bool send_eof(); bool send_eof();
virtual bool check_simple_select() const { return FALSE; } virtual bool check_simple_select() const { return FALSE; }
void abort(); void abort();
virtual void cleanup();
}; };

View File

@ -87,7 +87,7 @@ static int get_or_create_user_conn(THD *thd, const char *user,
my_malloc(sizeof(struct user_conn) + temp_len+1, my_malloc(sizeof(struct user_conn) + temp_len+1,
MYF(MY_WME))))) MYF(MY_WME)))))
{ {
net_send_error(thd, 0, NullS); // Out of memory /* MY_WME ensures an error is set in THD. */
return_val= 1; return_val= 1;
goto end; goto end;
} }
@ -100,8 +100,8 @@ static int get_or_create_user_conn(THD *thd, const char *user,
uc->reset_utime= thd->thr_create_utime; uc->reset_utime= thd->thr_create_utime;
if (my_hash_insert(&hash_user_connections, (uchar*) uc)) if (my_hash_insert(&hash_user_connections, (uchar*) uc))
{ {
/* The only possible error is out of memory, MY_WME sets an error. */
my_free((char*) uc,0); my_free((char*) uc,0);
net_send_error(thd, 0, NullS); // Out of memory
return_val= 1; return_val= 1;
goto end; goto end;
} }
@ -132,6 +132,7 @@ end:
1 error 1 error
*/ */
static
int check_for_max_user_connections(THD *thd, USER_CONN *uc) int check_for_max_user_connections(THD *thd, USER_CONN *uc)
{ {
int error=0; int error=0;
@ -141,7 +142,7 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc)
if (max_user_connections && !uc->user_resources.user_conn && if (max_user_connections && !uc->user_resources.user_conn &&
max_user_connections < (uint) uc->connections) max_user_connections < (uint) uc->connections)
{ {
net_printf_error(thd, ER_TOO_MANY_USER_CONNECTIONS, uc->user); my_error(ER_TOO_MANY_USER_CONNECTIONS, MYF(0), uc->user);
error=1; error=1;
goto end; goto end;
} }
@ -149,24 +150,24 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc)
if (uc->user_resources.user_conn && if (uc->user_resources.user_conn &&
uc->user_resources.user_conn < uc->connections) uc->user_resources.user_conn < uc->connections)
{ {
net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user,
"max_user_connections", "max_user_connections",
(long) uc->user_resources.user_conn); (long) uc->user_resources.user_conn);
error= 1; error= 1;
goto end; goto end;
} }
if (uc->user_resources.conn_per_hour && if (uc->user_resources.conn_per_hour &&
uc->user_resources.conn_per_hour <= uc->conn_per_hour) uc->user_resources.conn_per_hour <= uc->conn_per_hour)
{ {
net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user,
"max_connections_per_hour", "max_connections_per_hour",
(long) uc->user_resources.conn_per_hour); (long) uc->user_resources.conn_per_hour);
error=1; error=1;
goto end; goto end;
} }
uc->conn_per_hour++; uc->conn_per_hour++;
end: end:
if (error) if (error)
uc->connections--; // no need for decrease_user_connections() here uc->connections--; // no need for decrease_user_connections() here
(void) pthread_mutex_unlock(&LOCK_user_conn); (void) pthread_mutex_unlock(&LOCK_user_conn);
@ -258,8 +259,8 @@ bool check_mqh(THD *thd, uint check_command)
if (uc->user_resources.questions && if (uc->user_resources.questions &&
uc->questions++ >= uc->user_resources.questions) uc->questions++ >= uc->user_resources.questions)
{ {
net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, "max_questions", my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_questions",
(long) uc->user_resources.questions); (long) uc->user_resources.questions);
error=1; error=1;
goto end; goto end;
} }
@ -270,8 +271,8 @@ bool check_mqh(THD *thd, uint check_command)
(sql_command_flags[check_command] & CF_CHANGES_DATA) && (sql_command_flags[check_command] & CF_CHANGES_DATA) &&
uc->updates++ >= uc->user_resources.updates) uc->updates++ >= uc->user_resources.updates)
{ {
net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, "max_updates", my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_updates",
(long) uc->user_resources.updates); (long) uc->user_resources.updates);
error=1; error=1;
goto end; goto end;
} }
@ -284,55 +285,54 @@ end:
#endif /* NO_EMBEDDED_ACCESS_CHECKS */ #endif /* NO_EMBEDDED_ACCESS_CHECKS */
/* /**
Check if user exist and password supplied is correct. Check if user exist and password supplied is correct.
SYNOPSIS @param thd thread handle, thd->security_ctx->{host,user,ip} are used
check_user() @param command originator of the check: now check_user is called
thd thread handle, thd->security_ctx->{host,user,ip} are used during connect and change user procedures; used for
command originator of the check: now check_user is called logging.
during connect and change user procedures; used for @param passwd scrambled password received from client
logging. @param passwd_len length of scrambled password
passwd scrambled password received from client @param db database name to connect to, may be NULL
passwd_len length of scrambled password @param check_count TRUE if establishing a new connection. In this case
db database name to connect to, may be NULL check that we have not exceeded the global
check_count dont know exactly max_connections limist
Note, that host, user and passwd may point to communication buffer. @note Host, user and passwd may point to communication buffer.
Current implementation does not depend on that, but future changes Current implementation does not depend on that, but future changes
should be done with this in mind; 'thd' is INOUT, all other params should be done with this in mind; 'thd' is INOUT, all other params
are 'IN'. are 'IN'.
RETURN VALUE @retval 0 OK; thd->security_ctx->user/master_access/priv_user/db_access and
0 OK; thd->security_ctx->user/master_access/priv_user/db_access and thd->db are updated; OK is sent to the client.
thd->db are updated; OK is sent to client; @retval 1 error, e.g. access denied or handshake error, not sent to
-1 access denied or handshake error; error is sent to client; the client. A message is pushed into the error stack.
>0 error, not sent to client
*/ */
int check_user(THD *thd, enum enum_server_command command, int
check_user(THD *thd, enum enum_server_command command,
const char *passwd, uint passwd_len, const char *db, const char *passwd, uint passwd_len, const char *db,
bool check_count) bool check_count)
{ {
DBUG_ENTER("check_user"); DBUG_ENTER("check_user");
LEX_STRING db_str= { (char *) db, db ? strlen(db) : 0 }; LEX_STRING db_str= { (char *) db, db ? strlen(db) : 0 };
/*
Clear thd->db as it points to something, that will be freed when
connection is closed. We don't want to accidentally free a wrong
pointer if connect failed. Also in case of 'CHANGE USER' failure,
current database will be switched to 'no database selected'.
*/
thd->reset_db(NULL, 0);
#ifdef NO_EMBEDDED_ACCESS_CHECKS #ifdef NO_EMBEDDED_ACCESS_CHECKS
thd->main_security_ctx.master_access= GLOBAL_ACLS; // Full rights thd->main_security_ctx.master_access= GLOBAL_ACLS; // Full rights
/* Change database if necessary */ /* Change database if necessary */
if (db && db[0]) if (db && db[0])
{ {
/*
thd->db is saved in caller and needs to be freed by caller if this
function returns 0
*/
thd->reset_db(NULL, 0);
if (mysql_change_db(thd, &db_str, FALSE)) if (mysql_change_db(thd, &db_str, FALSE))
{ DBUG_RETURN(1);
/* Send the error to the client */
net_send_error(thd);
DBUG_RETURN(-1);
}
} }
send_ok(thd); send_ok(thd);
DBUG_RETURN(0); DBUG_RETURN(0);
@ -349,22 +349,17 @@ int check_user(THD *thd, enum enum_server_command command,
*/ */
if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323) if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323)
{ {
net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE); my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
DBUG_RETURN(-1); DBUG_RETURN(1);
} }
if (passwd_len != 0 && if (passwd_len != 0 &&
passwd_len != SCRAMBLE_LENGTH && passwd_len != SCRAMBLE_LENGTH &&
passwd_len != SCRAMBLE_LENGTH_323) passwd_len != SCRAMBLE_LENGTH_323)
DBUG_RETURN(ER_HANDSHAKE_ERROR); {
my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
/* DBUG_RETURN(1);
Clear thd->db as it points to something, that will be freed when }
connection is closed. We don't want to accidentally free a wrong pointer
if connect failed. Also in case of 'CHANGE USER' failure, current
database will be switched to 'no database selected'.
*/
thd->reset_db(NULL, 0);
USER_RESOURCES ur; USER_RESOURCES ur;
int res= acl_getroot(thd, &ur, passwd, passwd_len); int res= acl_getroot(thd, &ur, passwd, passwd_len);
@ -380,20 +375,21 @@ int check_user(THD *thd, enum enum_server_command command,
NET *net= &thd->net; NET *net= &thd->net;
if (opt_secure_auth_local) if (opt_secure_auth_local)
{ {
net_printf_error(thd, ER_SERVER_IS_IN_SECURE_AUTH_MODE, my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0),
thd->main_security_ctx.user, thd->main_security_ctx.user,
thd->main_security_ctx.host_or_ip); thd->main_security_ctx.host_or_ip);
general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE), general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
thd->main_security_ctx.user, thd->main_security_ctx.user,
thd->main_security_ctx.host_or_ip); thd->main_security_ctx.host_or_ip);
DBUG_RETURN(-1); DBUG_RETURN(1);
} }
/* We have to read very specific packet size */ /* We have to read very specific packet size */
if (send_old_password_request(thd) || if (send_old_password_request(thd) ||
my_net_read(net) != SCRAMBLE_LENGTH_323 + 1) my_net_read(net) != SCRAMBLE_LENGTH_323 + 1)
{ {
inc_host_errors(&thd->remote.sin_addr); inc_host_errors(&thd->remote.sin_addr);
DBUG_RETURN(ER_HANDSHAKE_ERROR); my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
DBUG_RETURN(1);
} }
/* Final attempt to check the user based on reply */ /* Final attempt to check the user based on reply */
/* So as passwd is short, errcode is always >= 0 */ /* So as passwd is short, errcode is always >= 0 */
@ -427,8 +423,8 @@ int check_user(THD *thd, enum enum_server_command command,
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
if (!count_ok) if (!count_ok)
{ // too many connections { // too many connections
net_send_error(thd, ER_CON_COUNT_ERROR); my_error(ER_CON_COUNT_ERROR, MYF(0));
DBUG_RETURN(-1); DBUG_RETURN(1);
} }
} }
@ -462,24 +458,29 @@ int check_user(THD *thd, enum enum_server_command command,
(opt_old_style_user_limits ? thd->main_security_ctx.host_or_ip : (opt_old_style_user_limits ? thd->main_security_ctx.host_or_ip :
thd->main_security_ctx.priv_host), thd->main_security_ctx.priv_host),
&ur)) &ur))
DBUG_RETURN(-1); {
/* The error is set by get_or_create_user_conn(). */
DBUG_RETURN(1);
}
if (thd->user_connect && if (thd->user_connect &&
(thd->user_connect->user_resources.conn_per_hour || (thd->user_connect->user_resources.conn_per_hour ||
thd->user_connect->user_resources.user_conn || thd->user_connect->user_resources.user_conn ||
max_user_connections) && max_user_connections) &&
check_for_max_user_connections(thd, thd->user_connect)) check_for_max_user_connections(thd, thd->user_connect))
DBUG_RETURN(-1); {
/* The error is set in check_for_max_user_connections(). */
DBUG_RETURN(1);
}
/* Change database if necessary */ /* Change database if necessary */
if (db && db[0]) if (db && db[0])
{ {
if (mysql_change_db(thd, &db_str, FALSE)) if (mysql_change_db(thd, &db_str, FALSE))
{ {
/* Send error to the client */ /* mysql_change_db() has pushed the error message. */
net_send_error(thd);
if (thd->user_connect) if (thd->user_connect)
decrease_user_connections(thd->user_connect); decrease_user_connections(thd->user_connect);
DBUG_RETURN(-1); DBUG_RETURN(1);
} }
} }
send_ok(thd); send_ok(thd);
@ -490,19 +491,19 @@ int check_user(THD *thd, enum enum_server_command command,
} }
else if (res == 2) // client gave short hash, server has long hash else if (res == 2) // client gave short hash, server has long hash
{ {
net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE); my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
DBUG_RETURN(-1); DBUG_RETURN(1);
} }
net_printf_error(thd, ER_ACCESS_DENIED_ERROR, my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
thd->main_security_ctx.user, thd->main_security_ctx.user,
thd->main_security_ctx.host_or_ip, thd->main_security_ctx.host_or_ip,
passwd_len ? ER(ER_YES) : ER(ER_NO)); passwd_len ? ER(ER_YES) : ER(ER_NO));
general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR), general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
thd->main_security_ctx.user, thd->main_security_ctx.user,
thd->main_security_ctx.host_or_ip, thd->main_security_ctx.host_or_ip,
passwd_len ? ER(ER_YES) : ER(ER_NO)); passwd_len ? ER(ER_YES) : ER(ER_NO));
DBUG_RETURN(-1); DBUG_RETURN(1);
#endif /* NO_EMBEDDED_ACCESS_CHECKS */ #endif /* NO_EMBEDDED_ACCESS_CHECKS */
} }
@ -666,9 +667,12 @@ static int check_connection(THD *thd)
char ip[30]; char ip[30];
if (vio_peer_addr(net->vio, ip, &thd->peer_port)) if (vio_peer_addr(net->vio, ip, &thd->peer_port))
return (ER_BAD_HOST_ERROR); {
if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(0)))) my_error(ER_BAD_HOST_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
return (ER_OUT_OF_RESOURCES); return 1;
}
if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(MY_WME))))
return 1; /* The error is set by my_strdup(). */
thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip; thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip;
vio_in_addr(net->vio,&thd->remote.sin_addr); vio_in_addr(net->vio,&thd->remote.sin_addr);
if (!(specialflag & SPECIAL_NO_RESOLVE)) if (!(specialflag & SPECIAL_NO_RESOLVE))
@ -685,7 +689,10 @@ static int check_connection(THD *thd)
thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host; thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
} }
if (connect_errors > max_connect_errors) if (connect_errors > max_connect_errors)
return(ER_HOST_IS_BLOCKED); {
my_error(ER_HOST_IS_BLOCKED, MYF(0), thd->main_security_ctx.host_or_ip);
return 1;
}
} }
DBUG_PRINT("info",("Host: %s ip: %s", DBUG_PRINT("info",("Host: %s ip: %s",
(thd->main_security_ctx.host ? (thd->main_security_ctx.host ?
@ -693,7 +700,11 @@ static int check_connection(THD *thd)
(thd->main_security_ctx.ip ? (thd->main_security_ctx.ip ?
thd->main_security_ctx.ip : "unknown ip"))); thd->main_security_ctx.ip : "unknown ip")));
if (acl_check_host(thd->main_security_ctx.host, thd->main_security_ctx.ip)) if (acl_check_host(thd->main_security_ctx.host, thd->main_security_ctx.ip))
return(ER_HOST_NOT_PRIVILEGED); {
my_error(ER_HOST_NOT_PRIVILEGED, MYF(0),
thd->main_security_ctx.host_or_ip);
return 1;
}
} }
else /* Hostname given means that the connection was on a socket */ else /* Hostname given means that the connection was on a socket */
{ {
@ -753,7 +764,9 @@ static int check_connection(THD *thd)
pkt_len < MIN_HANDSHAKE_SIZE) pkt_len < MIN_HANDSHAKE_SIZE)
{ {
inc_host_errors(&thd->remote.sin_addr); inc_host_errors(&thd->remote.sin_addr);
return(ER_HANDSHAKE_ERROR); my_error(ER_HANDSHAKE_ERROR, MYF(0),
thd->main_security_ctx.host_or_ip);
return 1;
} }
} }
#ifdef _CUSTOMCONFIG_ #ifdef _CUSTOMCONFIG_
@ -762,7 +775,7 @@ static int check_connection(THD *thd)
if (connect_errors) if (connect_errors)
reset_host_errors(&thd->remote.sin_addr); reset_host_errors(&thd->remote.sin_addr);
if (thd->packet.alloc(thd->variables.net_buffer_length)) if (thd->packet.alloc(thd->variables.net_buffer_length))
return(ER_OUT_OF_RESOURCES); return 1; /* The error is set by alloc(). */
thd->client_capabilities=uint2korr(net->read_pos); thd->client_capabilities=uint2korr(net->read_pos);
if (thd->client_capabilities & CLIENT_PROTOCOL_41) if (thd->client_capabilities & CLIENT_PROTOCOL_41)
@ -790,14 +803,16 @@ static int check_connection(THD *thd)
if (!ssl_acceptor_fd) if (!ssl_acceptor_fd)
{ {
inc_host_errors(&thd->remote.sin_addr); inc_host_errors(&thd->remote.sin_addr);
return(ER_HANDSHAKE_ERROR); my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
return 1;
} }
DBUG_PRINT("info", ("IO layer change in progress...")); DBUG_PRINT("info", ("IO layer change in progress..."));
if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout)) if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout))
{ {
DBUG_PRINT("error", ("Failed to accept new SSL connection")); DBUG_PRINT("error", ("Failed to accept new SSL connection"));
inc_host_errors(&thd->remote.sin_addr); inc_host_errors(&thd->remote.sin_addr);
return(ER_HANDSHAKE_ERROR); my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
return 1;
} }
DBUG_PRINT("info", ("Reading user information over SSL layer")); DBUG_PRINT("info", ("Reading user information over SSL layer"));
if ((pkt_len= my_net_read(net)) == packet_error || if ((pkt_len= my_net_read(net)) == packet_error ||
@ -806,7 +821,8 @@ static int check_connection(THD *thd)
DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)", DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
pkt_len)); pkt_len));
inc_host_errors(&thd->remote.sin_addr); inc_host_errors(&thd->remote.sin_addr);
return(ER_HANDSHAKE_ERROR); my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
return 1;
} }
} }
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
@ -814,7 +830,8 @@ static int check_connection(THD *thd)
if (end >= (char*) net->read_pos+ pkt_len +2) if (end >= (char*) net->read_pos+ pkt_len +2)
{ {
inc_host_errors(&thd->remote.sin_addr); inc_host_errors(&thd->remote.sin_addr);
return(ER_HANDSHAKE_ERROR); my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
return 1;
} }
if (thd->client_capabilities & CLIENT_INTERACTIVE) if (thd->client_capabilities & CLIENT_INTERACTIVE)
@ -851,7 +868,8 @@ static int check_connection(THD *thd)
if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len) if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
{ {
inc_host_errors(&thd->remote.sin_addr); inc_host_errors(&thd->remote.sin_addr);
return ER_HANDSHAKE_ERROR; my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
return 1;
} }
/* Since 4.1 all database names are stored in utf8 */ /* Since 4.1 all database names are stored in utf8 */
@ -879,8 +897,8 @@ static int check_connection(THD *thd)
if (thd->main_security_ctx.user) if (thd->main_security_ctx.user)
x_free(thd->main_security_ctx.user); x_free(thd->main_security_ctx.user);
if (!(thd->main_security_ctx.user= my_strdup(user, MYF(0)))) if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME))))
return (ER_OUT_OF_RESOURCES); return 1; /* The error is set by my_strdup(). */
return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE); return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);
} }
@ -929,9 +947,7 @@ bool setup_connection_thread_globals(THD *thd)
bool login_connection(THD *thd) bool login_connection(THD *thd)
{ {
int error;
NET *net= &thd->net; NET *net= &thd->net;
Security_context *sctx= thd->security_ctx;
DBUG_ENTER("login_connection"); DBUG_ENTER("login_connection");
DBUG_PRINT("info", ("login_connection called by thread %lu", DBUG_PRINT("info", ("login_connection called by thread %lu",
thd->thread_id)); thd->thread_id));
@ -942,10 +958,9 @@ bool login_connection(THD *thd)
my_net_set_read_timeout(net, connect_timeout); my_net_set_read_timeout(net, connect_timeout);
my_net_set_write_timeout(net, connect_timeout); my_net_set_write_timeout(net, connect_timeout);
if ((error=check_connection(thd))) if (check_connection(thd))
{ // Wrong permissions { // Wrong permissions
if (error > 0) net_send_error(thd);
net_printf_error(thd, error, sctx->host_or_ip);
#ifdef __NT__ #ifdef __NT__
if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE) if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)
my_sleep(1000); /* must wait after eof() */ my_sleep(1000); /* must wait after eof() */
@ -975,12 +990,12 @@ void end_connection(THD *thd)
decrease_user_connections(thd->user_connect); decrease_user_connections(thd->user_connect);
if (thd->killed || if (thd->killed ||
net->error && net->vio != 0 && net->report_error) net->error && net->vio != 0 && thd->is_error())
{ {
statistic_increment(aborted_threads,&LOCK_status); statistic_increment(aborted_threads,&LOCK_status);
} }
if (net->error && net->vio != 0 && net->report_error) if (net->error && net->vio != 0 && thd->is_error())
{ {
if (!thd->killed && thd->variables.log_warnings > 1) if (!thd->killed && thd->variables.log_warnings > 1)
{ {
@ -1030,7 +1045,17 @@ static void prepare_new_connection_state(THD* thd)
if (sys_init_connect.value_length && !(sctx->master_access & SUPER_ACL)) if (sys_init_connect.value_length && !(sctx->master_access & SUPER_ACL))
{ {
execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect); execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
if (thd->query_error) /*
execute_init_command calls net_send_error.
If there was an error during execution of the init statements,
the error at this moment is present in thd->net.last_error and also
thd->is_slave_error and thd->net.report_error are set.
net_send_error sends the contents of thd->net.last_error and
clears thd->net.report_error. It doesn't, however, clean
thd->is_slave_error or thd->net.last_error. Here we make use of this
fact.
*/
if (thd->is_slave_error)
{ {
thd->killed= THD::KILL_CONNECTION; thd->killed= THD::KILL_CONNECTION;
sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION), sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),

View File

@ -35,6 +35,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
READ_RECORD info; READ_RECORD info;
bool using_limit=limit != HA_POS_ERROR; bool using_limit=limit != HA_POS_ERROR;
bool transactional_table, safe_update, const_cond; bool transactional_table, safe_update, const_cond;
bool const_cond_result;
ha_rows deleted= 0; ha_rows deleted= 0;
uint usable_index= MAX_KEY; uint usable_index= MAX_KEY;
SELECT_LEX *select_lex= &thd->lex->select_lex; SELECT_LEX *select_lex= &thd->lex->select_lex;
@ -86,6 +87,12 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
select_lex->no_error= thd->lex->ignore; select_lex->no_error= thd->lex->ignore;
const_cond_result= const_cond && (!conds || conds->val_int());
if (thd->is_error())
{
/* Error evaluating val_int(). */
DBUG_RETURN(TRUE);
}
/* /*
Test if the user wants to delete all rows and deletion doesn't have Test if the user wants to delete all rows and deletion doesn't have
any side-effects (because of triggers), so we can use optimized any side-effects (because of triggers), so we can use optimized
@ -105,7 +112,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
- We should not be binlogging this statement row-based, and - We should not be binlogging this statement row-based, and
- there should be no delete triggers associated with the table. - there should be no delete triggers associated with the table.
*/ */
if (!using_limit && const_cond && (!conds || conds->val_int()) && if (!using_limit && const_cond_result &&
!(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) && !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) &&
(thd->lex->sql_command == SQLCOM_TRUNCATE || (thd->lex->sql_command == SQLCOM_TRUNCATE ||
(!thd->current_stmt_binlog_row_based && (!thd->current_stmt_binlog_row_based &&
@ -252,10 +259,10 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
table->mark_columns_needed_for_delete(); table->mark_columns_needed_for_delete();
while (!(error=info.read_record(&info)) && !thd->killed && while (!(error=info.read_record(&info)) && !thd->killed &&
!thd->net.report_error) ! thd->is_error())
{ {
// thd->net.report_error is tested to disallow delete row on error // thd->is_error() is tested to disallow delete row on error
if (!(select && select->skip_record())&& !thd->net.report_error ) if (!(select && select->skip_record())&& ! thd->is_error() )
{ {
if (table->triggers && if (table->triggers &&
@ -300,7 +307,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
else else
table->file->unlock_row(); // Row failed selection, release lock on it table->file->unlock_row(); // Row failed selection, release lock on it
} }
if (thd->killed && !error) if (thd->killed || thd->is_error())
error= 1; // Aborted error= 1; // Aborted
if (will_batch && (loc_error= table->file->end_bulk_delete())) if (will_batch && (loc_error= table->file->end_bulk_delete()))
{ {
@ -389,7 +396,7 @@ cleanup:
send_ok(thd, (ha_rows) thd->row_count_func); send_ok(thd, (ha_rows) thd->row_count_func);
DBUG_PRINT("info",("%ld records deleted",(long) deleted)); DBUG_PRINT("info",("%ld records deleted",(long) deleted));
} }
DBUG_RETURN(error >= 0 || thd->net.report_error); DBUG_RETURN(error >= 0 || thd->is_error());
} }

View File

@ -137,7 +137,7 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
level= MYSQL_ERROR::WARN_LEVEL_ERROR; level= MYSQL_ERROR::WARN_LEVEL_ERROR;
} }
if (thd->handle_error(code, level)) if (thd->handle_error(code, msg, level))
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
if (thd->spcont && if (thd->spcont &&

View File

@ -151,6 +151,14 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables)
} }
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
} }
else if (tables->table)
{
/* Must be a temporary table */
TABLE *table= tables->table;
table->file->ha_index_or_rnd_end();
table->query_id= thd->query_id;
table->open_by_handler= 0;
}
} }
/* /*
@ -282,6 +290,12 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
goto err; goto err;
} }
/*
If it's a temp table, don't reset table->query_id as the table is
being used by this handler. Otherwise, no meaning at all.
*/
tables->table->open_by_handler= 1;
if (! reopen) if (! reopen)
send_ok(thd); send_ok(thd);
DBUG_PRINT("exit",("OK")); DBUG_PRINT("exit",("OK"));

View File

@ -738,7 +738,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
table->triggers, table->triggers,
TRG_EVENT_INSERT)) TRG_EVENT_INSERT))
{ {
if (values_list.elements != 1 && !thd->net.report_error) if (values_list.elements != 1 && ! thd->is_error())
{ {
info.records++; info.records++;
continue; continue;
@ -769,7 +769,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
table->triggers, table->triggers,
TRG_EVENT_INSERT)) TRG_EVENT_INSERT))
{ {
if (values_list.elements != 1 && ! thd->net.report_error) if (values_list.elements != 1 && ! thd->is_error())
{ {
info.records++; info.records++;
continue; continue;
@ -1909,7 +1909,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
thd_proc_info(thd, "got old table"); thd_proc_info(thd, "got old table");
if (di->thd.killed) if (di->thd.killed)
{ {
if (di->thd.net.report_error) if (di->thd.is_error())
{ {
/* /*
Copy the error message. Note that we don't treat fatal Copy the error message. Note that we don't treat fatal
@ -1940,7 +1940,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
pthread_mutex_unlock(&di->mutex); pthread_mutex_unlock(&di->mutex);
if (table_list->table) if (table_list->table)
{ {
DBUG_ASSERT(thd->net.report_error == 0); DBUG_ASSERT(! thd->is_error());
thd->di= di; thd->di= di;
} }
/* Unlock the delayed insert object after its last access. */ /* Unlock the delayed insert object after its last access. */
@ -1949,7 +1949,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
end_create: end_create:
pthread_mutex_unlock(&LOCK_delayed_create); pthread_mutex_unlock(&LOCK_delayed_create);
DBUG_RETURN(thd->net.report_error); DBUG_RETURN(thd->is_error());
} }
@ -3015,7 +3015,7 @@ bool select_insert::send_data(List<Item> &values)
thd->count_cuted_fields= CHECK_FIELD_WARN; // Calculate cuted fields thd->count_cuted_fields= CHECK_FIELD_WARN; // Calculate cuted fields
store_values(values); store_values(values);
thd->count_cuted_fields= CHECK_FIELD_IGNORE; thd->count_cuted_fields= CHECK_FIELD_IGNORE;
if (thd->net.report_error) if (thd->is_error())
DBUG_RETURN(1); DBUG_RETURN(1);
if (table_list) // Not CREATE ... SELECT if (table_list) // Not CREATE ... SELECT
{ {
@ -3399,7 +3399,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
it preparable for open. But let us do close_temporary_table() here it preparable for open. But let us do close_temporary_table() here
just in case. just in case.
*/ */
close_temporary_table(thd, create_table); drop_temporary_table(thd, create_table);
} }
} }
} }

View File

@ -1623,7 +1623,7 @@ typedef struct st_lex : public Query_tables_list
uint8 create_view_algorithm; uint8 create_view_algorithm;
uint8 create_view_check; uint8 create_view_check;
bool drop_if_exists, drop_temporary, local_file, one_shot_set; bool drop_if_exists, drop_temporary, local_file, one_shot_set;
bool autocommit;
bool verbose, no_write_to_binlog; bool verbose, no_write_to_binlog;
bool tx_chain, tx_release; bool tx_chain, tx_release;

View File

@ -442,7 +442,7 @@ pthread_handler_t handle_bootstrap(void *arg)
if (thd->is_fatal_error) if (thd->is_fatal_error)
break; break;
if (thd->net.report_error) if (thd->is_error())
{ {
/* The query failed, send error to log and abort bootstrap */ /* The query failed, send error to log and abort bootstrap */
net_send_error(thd); net_send_error(thd);
@ -934,15 +934,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
/* Clear variables that are allocated */ /* Clear variables that are allocated */
thd->user_connect= 0; thd->user_connect= 0;
thd->security_ctx->priv_user= thd->security_ctx->user;
res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE); res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
if (res) if (res)
{ {
/* authentication failure, we shall restore old user */
if (res > 0)
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
else
thd->clear_error(); // Error already sent to client
x_free(thd->security_ctx->user); x_free(thd->security_ctx->user);
*thd->security_ctx= save_security_ctx; *thd->security_ctx= save_security_ctx;
thd->user_connect= save_user_connect; thd->user_connect= save_user_connect;
@ -956,8 +952,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (save_user_connect) if (save_user_connect)
decrease_user_connections(save_user_connect); decrease_user_connections(save_user_connect);
#endif /* NO_EMBEDDED_ACCESS_CHECKS */ #endif /* NO_EMBEDDED_ACCESS_CHECKS */
x_free((uchar*) save_db); x_free(save_db);
x_free((uchar*) save_security_ctx.user); x_free(save_security_ctx.user);
if (cs_number) if (cs_number)
{ {
@ -1016,16 +1012,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
mysql_parse(thd, thd->query, thd->query_length, &end_of_stmt); mysql_parse(thd, thd->query, thd->query_length, &end_of_stmt);
while (!thd->killed && (end_of_stmt != NULL) && !thd->net.report_error) while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
{ {
char *beginning_of_next_stmt= (char*) end_of_stmt; char *beginning_of_next_stmt= (char*) end_of_stmt;
net->no_send_error= 0; net->no_send_error= 0;
/* /*
Multiple queries exits, execute them individually Multiple queries exits, execute them individually
*/ */
if (thd->lock || thd->open_tables || thd->derived_tables || close_thread_tables(thd);
thd->prelocked_mode)
close_thread_tables(thd);
ulong length= (ulong)(packet_end - beginning_of_next_stmt); ulong length= (ulong)(packet_end - beginning_of_next_stmt);
log_slow_statement(thd); log_slow_statement(thd);
@ -1369,12 +1363,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
break; break;
} }
if (thd->lock || thd->open_tables || thd->derived_tables ||
thd->prelocked_mode) thd_proc_info(thd, "closing tables");
{ /* Free tables */
thd_proc_info(thd, "closing tables"); close_thread_tables(thd);
close_thread_tables(thd); /* Free tables */
}
/* /*
assume handlers auto-commit (if some doesn't - transaction handling assume handlers auto-commit (if some doesn't - transaction handling
in MySQL should be redesigned to support it; it's a big change, in MySQL should be redesigned to support it; it's a big change,
@ -1388,9 +1381,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->transaction.xid_state.xid.null(); thd->transaction.xid_state.xid.null();
/* report error issued during command execution */ /* report error issued during command execution */
if (thd->killed_errno() && !thd->net.report_error) if (thd->killed_errno() && ! thd->is_error())
thd->send_kill_message(); thd->send_kill_message();
if (thd->net.report_error) if (thd->is_error())
net_send_error(thd); net_send_error(thd);
log_slow_statement(thd); log_slow_statement(thd);
@ -3110,6 +3103,10 @@ end_with_restore_list:
case SQLCOM_SET_OPTION: case SQLCOM_SET_OPTION:
{ {
List<set_var_base> *lex_var_list= &lex->var_list; List<set_var_base> *lex_var_list= &lex->var_list;
if (lex->autocommit && end_active_trans(thd))
goto error;
if ((check_table_access(thd, SELECT_ACL, all_tables, 0) || if ((check_table_access(thd, SELECT_ACL, all_tables, 0) ||
open_and_lock_tables(thd, all_tables))) open_and_lock_tables(thd, all_tables)))
goto error; goto error;
@ -3987,7 +3984,7 @@ create_sp_error:
thd->row_count_func)); thd->row_count_func));
else else
{ {
DBUG_ASSERT(thd->net.report_error == 1 || thd->killed); DBUG_ASSERT(thd->is_error() || thd->killed);
goto error; // Substatement should already have sent error goto error; // Substatement should already have sent error
} }
} }
@ -4579,7 +4576,7 @@ finish:
*/ */
start_waiting_global_read_lock(thd); start_waiting_global_read_lock(thd);
} }
DBUG_RETURN(res || thd->net.report_error); DBUG_RETURN(res || thd->is_error());
} }
@ -5524,7 +5521,7 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
else else
#endif #endif
{ {
if (! thd->net.report_error) if (! thd->is_error())
{ {
/* /*
Binlog logs a string starting from thd->query and having length Binlog logs a string starting from thd->query and having length
@ -5548,7 +5545,7 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
} }
else else
{ {
DBUG_ASSERT(thd->net.report_error); DBUG_ASSERT(thd->is_error());
DBUG_PRINT("info",("Command aborted. Fatal_error: %d", DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
thd->is_fatal_error)); thd->is_fatal_error));
@ -6368,7 +6365,7 @@ void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
RETURN RETURN
0 ok 0 ok
!=0 error. thd->killed or thd->net.report_error is set !=0 error. thd->killed or thd->is_error() is set
*/ */
bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
@ -7331,10 +7328,10 @@ bool parse_sql(THD *thd,
bool mysql_parse_status= MYSQLparse(thd) != 0; bool mysql_parse_status= MYSQLparse(thd) != 0;
/* Check that if MYSQLparse() failed, thd->net.report_error is set. */ /* Check that if MYSQLparse() failed, thd->is_error() is set. */
DBUG_ASSERT(!mysql_parse_status || DBUG_ASSERT(!mysql_parse_status ||
mysql_parse_status && thd->net.report_error); mysql_parse_status && thd->is_error());
/* Reset Lex_input_stream. */ /* Reset Lex_input_stream. */

View File

@ -2867,7 +2867,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
lex_start(thd); lex_start(thd);
error= parse_sql(thd, &lip, NULL) || error= parse_sql(thd, &lip, NULL) ||
thd->net.report_error || thd->is_error() ||
init_param_array(this); init_param_array(this);
lex->set_trg_event_type_for_tables(); lex->set_trg_event_type_for_tables();

View File

@ -122,7 +122,7 @@ static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table,
static enum_nested_loop_state static enum_nested_loop_state
evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
int error, my_bool *report_error); int error);
static enum_nested_loop_state static enum_nested_loop_state
evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab); evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab);
static enum_nested_loop_state static enum_nested_loop_state
@ -263,8 +263,8 @@ bool handle_select(THD *thd, LEX *lex, select_result *result,
result, unit, select_lex); result, unit, select_lex);
} }
DBUG_PRINT("info",("res: %d report_error: %d", res, DBUG_PRINT("info",("res: %d report_error: %d", res,
thd->net.report_error)); thd->is_error()));
res|= thd->net.report_error; res|= thd->is_error();
if (unlikely(res)) if (unlikely(res))
result->abort(); result->abort();
@ -491,7 +491,7 @@ JOIN::prepare(Item ***rref_pointer_array,
(having->fix_fields(thd, &having) || (having->fix_fields(thd, &having) ||
having->check_cols(1))); having->check_cols(1)));
select_lex->having_fix_field= 0; select_lex->having_fix_field= 0;
if (having_fix_rc || thd->net.report_error) if (having_fix_rc || thd->is_error())
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
thd->lex->allow_sum_func= save_allow_sum_func; thd->lex->allow_sum_func= save_allow_sum_func;
} }
@ -818,7 +818,7 @@ JOIN::optimize()
} }
conds= optimize_cond(this, conds, join_list, &cond_value); conds= optimize_cond(this, conds, join_list, &cond_value);
if (thd->net.report_error) if (thd->is_error())
{ {
error= 1; error= 1;
DBUG_PRINT("error",("Error from optimize_cond")); DBUG_PRINT("error",("Error from optimize_cond"));
@ -827,7 +827,7 @@ JOIN::optimize()
{ {
having= optimize_cond(this, having, join_list, &having_value); having= optimize_cond(this, having, join_list, &having_value);
if (thd->net.report_error) if (thd->is_error())
{ {
error= 1; error= 1;
DBUG_PRINT("error",("Error from optimize_cond")); DBUG_PRINT("error",("Error from optimize_cond"));
@ -1039,7 +1039,7 @@ JOIN::optimize()
{ {
ORDER *org_order= order; ORDER *org_order= order;
order=remove_const(this, order,conds,1, &simple_order); order=remove_const(this, order,conds,1, &simple_order);
if (thd->net.report_error) if (thd->is_error())
{ {
error= 1; error= 1;
DBUG_PRINT("error",("Error from remove_const")); DBUG_PRINT("error",("Error from remove_const"));
@ -1170,7 +1170,7 @@ JOIN::optimize()
group_list= remove_const(this, (old_group_list= group_list), conds, group_list= remove_const(this, (old_group_list= group_list), conds,
rollup.state == ROLLUP::STATE_NONE, rollup.state == ROLLUP::STATE_NONE,
&simple_group); &simple_group);
if (thd->net.report_error) if (thd->is_error())
{ {
error= 1; error= 1;
DBUG_PRINT("error",("Error from remove_const")); DBUG_PRINT("error",("Error from remove_const"));
@ -1193,7 +1193,7 @@ JOIN::optimize()
{ {
group_list= procedure->group= remove_const(this, procedure->group, conds, group_list= procedure->group= remove_const(this, procedure->group, conds,
1, &simple_group); 1, &simple_group);
if (thd->net.report_error) if (thd->is_error())
{ {
error= 1; error= 1;
DBUG_PRINT("error",("Error from remove_const")); DBUG_PRINT("error",("Error from remove_const"));
@ -2116,10 +2116,10 @@ JOIN::exec()
} }
} }
} }
/* XXX: When can we have here thd->net.report_error not zero? */ /* XXX: When can we have here thd->is_error() not zero? */
if (thd->net.report_error) if (thd->is_error())
{ {
error= thd->net.report_error; error= thd->is_error();
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
curr_join->having= curr_join->tmp_having; curr_join->having= curr_join->tmp_having;
@ -2325,7 +2325,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
join->having_history= (join->having?join->having:join->tmp_having); join->having_history= (join->having?join->having:join->tmp_having);
} }
if (thd->net.report_error) if (thd->is_error())
goto err; goto err;
join->exec(); join->exec();
@ -2351,8 +2351,7 @@ err:
{ {
thd_proc_info(thd, "end"); thd_proc_info(thd, "end");
err|= select_lex->cleanup(); err|= select_lex->cleanup();
thd_proc_info(thd, "end"); DBUG_RETURN(err || thd->is_error());
DBUG_RETURN(err || thd->net.report_error);
} }
DBUG_RETURN(join->error); DBUG_RETURN(join->error);
} }
@ -6670,7 +6669,7 @@ void JOIN::cleanup(bool full)
for (tab= join_tab, end= tab+tables; tab != end; tab++) for (tab= join_tab, end= tab+tables; tab != end; tab++)
{ {
if (tab->table) if (tab->table)
tab->table->file->ha_index_or_rnd_end(); tab->table->file->ha_index_or_rnd_end();
} }
} }
} }
@ -10729,7 +10728,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
DBUG_PRINT("error",("Error: do_select() failed")); DBUG_PRINT("error",("Error: do_select() failed"));
} }
#endif #endif
DBUG_RETURN(join->thd->net.report_error ? -1 : rc); DBUG_RETURN(join->thd->is_error() ? -1 : rc);
} }
@ -10883,7 +10882,6 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
int error; int error;
enum_nested_loop_state rc; enum_nested_loop_state rc;
my_bool *report_error= &(join->thd->net.report_error);
READ_RECORD *info= &join_tab->read_record; READ_RECORD *info= &join_tab->read_record;
if (join->resume_nested_loop) if (join->resume_nested_loop)
@ -10915,13 +10913,13 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
join->thd->row_count= 0; join->thd->row_count= 0;
error= (*join_tab->read_first_record)(join_tab); error= (*join_tab->read_first_record)(join_tab);
rc= evaluate_join_record(join, join_tab, error, report_error); rc= evaluate_join_record(join, join_tab, error);
} }
while (rc == NESTED_LOOP_OK) while (rc == NESTED_LOOP_OK)
{ {
error= info->read_record(info); error= info->read_record(info);
rc= evaluate_join_record(join, join_tab, error, report_error); rc= evaluate_join_record(join, join_tab, error);
} }
if (rc == NESTED_LOOP_NO_MORE_ROWS && if (rc == NESTED_LOOP_NO_MORE_ROWS &&
@ -10945,13 +10943,13 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
static enum_nested_loop_state static enum_nested_loop_state
evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
int error, my_bool *report_error) int error)
{ {
bool not_used_in_distinct=join_tab->not_used_in_distinct; bool not_used_in_distinct=join_tab->not_used_in_distinct;
ha_rows found_records=join->found_records; ha_rows found_records=join->found_records;
COND *select_cond= join_tab->select_cond; COND *select_cond= join_tab->select_cond;
if (error > 0 || (*report_error)) // Fatal error if (error > 0 || (join->thd->is_error())) // Fatal error
return NESTED_LOOP_ERROR; return NESTED_LOOP_ERROR;
if (error < 0) if (error < 0)
return NESTED_LOOP_NO_MORE_ROWS; return NESTED_LOOP_NO_MORE_ROWS;
@ -16062,7 +16060,7 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
first->options | thd->options | SELECT_DESCRIBE, first->options | thd->options | SELECT_DESCRIBE,
result, unit, first); result, unit, first);
} }
DBUG_RETURN(res || thd->net.report_error); DBUG_RETURN(res || thd->is_error());
} }

View File

@ -434,7 +434,7 @@ static uint read_ddl_log_header()
create_ddl_log_file_name(file_name); create_ddl_log_file_name(file_name);
if ((global_ddl_log.file_id= my_open(file_name, if ((global_ddl_log.file_id= my_open(file_name,
O_RDWR | O_BINARY, MYF(MY_WME))) >= 0) O_RDWR | O_BINARY, MYF(0))) >= 0)
{ {
if (read_ddl_log_file_entry(0UL)) if (read_ddl_log_file_entry(0UL))
{ {
@ -1503,7 +1503,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
char path[FN_REFLEN], *alias; char path[FN_REFLEN], *alias;
uint path_length; uint path_length;
String wrong_tables; String wrong_tables;
int error; int error= 0;
int non_temp_tables_count= 0; int non_temp_tables_count= 0;
bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0; bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
String built_query; String built_query;
@ -1563,10 +1563,27 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
enum legacy_db_type frm_db_type; enum legacy_db_type frm_db_type;
mysql_ha_flush(thd, table, MYSQL_HA_CLOSE_FINAL, 1); mysql_ha_flush(thd, table, MYSQL_HA_CLOSE_FINAL, 1);
if (!close_temporary_table(thd, table))
{ error= drop_temporary_table(thd, table);
tmp_table_deleted=1;
continue; // removed temporary table switch (error) {
case 0:
// removed temporary table
tmp_table_deleted= 1;
continue;
case -1:
// table already in use
/*
XXX: This branch should never be taken outside of SF, trigger or
prelocked mode.
DBUG_ASSERT(thd->in_sub_stmt);
*/
error= 1;
goto err_with_placeholders;
default:
// temporary table not found
error= 0;
} }
/* /*
@ -1593,7 +1610,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
built_query.append("`,"); built_query.append("`,");
} }
error=0;
table_type= table->db_type; table_type= table->db_type;
if (!drop_temporary) if (!drop_temporary)
{ {
@ -2380,8 +2396,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
sql_field->length= dup_field->char_length; sql_field->length= dup_field->char_length;
sql_field->pack_length= dup_field->pack_length; sql_field->pack_length= dup_field->pack_length;
sql_field->key_length= dup_field->key_length; sql_field->key_length= dup_field->key_length;
sql_field->create_length_to_internal_length();
sql_field->decimals= dup_field->decimals; sql_field->decimals= dup_field->decimals;
sql_field->create_length_to_internal_length();
sql_field->unireg_check= dup_field->unireg_check; sql_field->unireg_check= dup_field->unireg_check;
/* /*
We're making one field from two, the result field will have We're making one field from two, the result field will have
@ -4985,6 +5001,7 @@ compare_tables(TABLE *table,
create_info->used_fields & HA_CREATE_USED_ENGINE || create_info->used_fields & HA_CREATE_USED_ENGINE ||
create_info->used_fields & HA_CREATE_USED_CHARSET || create_info->used_fields & HA_CREATE_USED_CHARSET ||
create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET || create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET ||
create_info->used_fields & HA_CREATE_USED_ROW_FORMAT ||
(alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) || (alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
order_num || order_num ||
!table->s->mysql_version || !table->s->mysql_version ||
@ -5200,7 +5217,8 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
if (error == HA_ERR_WRONG_COMMAND) if (error == HA_ERR_WRONG_COMMAND)
{ {
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE, push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), table->s->table_name); ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
table->s->table_name.str);
error= 0; error= 0;
} else if (error) } else if (error)
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
@ -5392,7 +5410,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
{ {
if (def->change && ! def->field) if (def->change && ! def->field)
{ {
my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name); my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name.str);
goto err; goto err;
} }
/* /*
@ -5427,7 +5445,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
} }
if (!find) if (!find)
{ {
my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->s->table_name); my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->s->table_name.str);
goto err; goto err;
} }
find_it.after(def); // Put element after this find_it.after(def); // Put element after this
@ -5437,7 +5455,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
if (alter_info->alter_list.elements) if (alter_info->alter_list.elements)
{ {
my_error(ER_BAD_FIELD_ERROR, MYF(0), my_error(ER_BAD_FIELD_ERROR, MYF(0),
alter_info->alter_list.head()->name, table->s->table_name); alter_info->alter_list.head()->name, table->s->table_name.str);
goto err; goto err;
} }
if (!new_create_list.elements) if (!new_create_list.elements)

View File

@ -58,7 +58,7 @@ bool select_union::send_data(List<Item> &values)
return 0; return 0;
} }
fill_record(thd, table->field, values, 1); fill_record(thd, table->field, values, 1);
if (thd->net.report_error) if (thd->is_error())
return 1; return 1;
if ((error= table->file->ha_write_row(table->record[0]))) if ((error= table->file->ha_write_row(table->record[0])))

View File

@ -679,7 +679,7 @@ int mysql_update(THD *thd,
*/ */
if (will_batch && if (will_batch &&
((error= table->file->exec_bulk_update(&dup_key_found)) || ((error= table->file->exec_bulk_update(&dup_key_found)) ||
!dup_key_found)) dup_key_found))
{ {
if (error) if (error)
{ {
@ -844,7 +844,7 @@ int mysql_update(THD *thd,
} }
thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */ thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
thd->abort_on_warning= 0; thd->abort_on_warning= 0;
DBUG_RETURN((error >= 0 || thd->net.report_error) ? 1 : 0); DBUG_RETURN((error >= 0 || thd->is_error()) ? 1 : 0);
err: err:
delete select; delete select;
@ -1193,8 +1193,8 @@ bool mysql_multi_update(THD *thd,
OPTION_SETUP_TABLES_DONE, OPTION_SETUP_TABLES_DONE,
result, unit, select_lex); result, unit, select_lex);
DBUG_PRINT("info",("res: %d report_error: %d", res, DBUG_PRINT("info",("res: %d report_error: %d", res,
thd->net.report_error)); (int) thd->is_error()));
res|= thd->net.report_error; res|= thd->is_error();
if (unlikely(res)) if (unlikely(res))
{ {
/* If we had a another error reported earlier then this will be ignored */ /* If we had a another error reported earlier then this will be ignored */

Some files were not shown because too many files have changed in this diff Show More