Merge lambda.hsd1.co.comcast.net.:/home/malff/TREE/mysql-5.1-base
into lambda.hsd1.co.comcast.net.:/home/malff/TREE/mysql-5.1-rt-merge sql/handler.cc: Auto merged sql/log_event.cc: Auto merged sql/sql_update.cc: Auto merged
This commit is contained in:
commit
56d00051a0
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -2251,7 +2251,7 @@ EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
|
|||||||
(SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12;
|
(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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
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
|
2 SUBQUERY t1 range NULL a 5 NULL 8
|
||||||
EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
|
EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
|
||||||
a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
|
a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
@ -2268,7 +2268,7 @@ AND t1_outer1.b = t1_outer2.b;
|
|||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY t1_outer1 ref a a 5 const 1 Using where; Using index
|
1 PRIMARY t1_outer1 ref a a 5 const 1 Using where; Using index
|
||||||
1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer
|
1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer
|
||||||
2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by
|
2 SUBQUERY t1 range NULL a 5 NULL 8
|
||||||
EXPLAIN SELECT (SELECT (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) x
|
EXPLAIN SELECT (SELECT (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) x
|
||||||
FROM t1 AS t1_outer) x2 FROM t1 AS t1_outer2;
|
FROM t1 AS t1_outer) x2 FROM t1 AS t1_outer2;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -286,7 +286,7 @@ NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
|
|||||||
explain select * from (select * from t1 where key1 = 3 or key2 =3) as Z where key8 >5;
|
explain select * from (select * from t1 where key1 = 3 or key2 =3) as Z where key8 >5;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
|
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
|
||||||
2 DERIVED t1 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where; Using index
|
2 DERIVED t1 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where
|
||||||
create table t3 like t0;
|
create table t3 like t0;
|
||||||
insert into t3 select * from t0;
|
insert into t3 select * from t0;
|
||||||
alter table t3 add key9 int not null, add index i9(key9);
|
alter table t3 add key9 int not null, add index i9(key9);
|
||||||
|
@ -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` (
|
||||||
|
@ -530,3 +530,18 @@ 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;
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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%';
|
||||||
|
@ -501,3 +501,26 @@ 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;
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -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
|
||||||
#
|
#
|
||||||
|
@ -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);
|
||||||
|
@ -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]);
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,7 +679,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);
|
||||||
@ -920,7 +920,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);
|
||||||
@ -1420,7 +1419,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);
|
||||||
|
@ -2583,7 +2583,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);
|
||||||
|
|
||||||
@ -2593,7 +2593,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);
|
||||||
@ -4302,6 +4302,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++;
|
||||||
@ -4320,7 +4321,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;
|
||||||
|
122
sql/protocol.cc
122
sql/protocol.cc
@ -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.
|
||||||
|
@ -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);
|
||||||
|
@ -3051,7 +3051,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++))
|
||||||
|
@ -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 = "Opening master dump table";
|
thd->proc_info = "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");
|
||||||
|
@ -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
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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))
|
||||||
|
156
sql/sql_base.cc
156
sql/sql_base.cc
@ -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);
|
||||||
|
@ -395,7 +395,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;
|
||||||
@ -498,12 +498,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
|
||||||
@ -1305,23 +1305,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();
|
||||||
@ -1331,6 +1334,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)
|
||||||
@ -1368,7 +1382,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);
|
||||||
@ -1389,10 +1403,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
|
||||||
@ -2404,6 +2418,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
|
||||||
|
@ -969,6 +969,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;
|
||||||
};
|
};
|
||||||
@ -1466,7 +1467,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;
|
||||||
@ -1695,7 +1703,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; }
|
||||||
@ -1709,6 +1717,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();
|
||||||
|
|
||||||
@ -1902,7 +1924,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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2029,14 +2051,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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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),
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 &&
|
||||||
|
@ -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"));
|
||||||
|
@ -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="got old table";
|
thd->proc_info="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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1616,7 +1616,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;
|
||||||
|
@ -436,7 +436,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);
|
||||||
@ -911,15 +911,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;
|
||||||
@ -933,8 +929,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)
|
||||||
{
|
{
|
||||||
@ -990,16 +986,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
|
|
||||||
mysql_parse(thd, thd->query, thd->query_length, & found_semicolon);
|
mysql_parse(thd, thd->query, thd->query_length, & found_semicolon);
|
||||||
|
|
||||||
while (!thd->killed && found_semicolon && !thd->net.report_error)
|
while (!thd->killed && found_semicolon && ! thd->is_error())
|
||||||
{
|
{
|
||||||
char *next_packet= (char*) found_semicolon;
|
char *next_packet= (char*) found_semicolon;
|
||||||
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 - next_packet);
|
ulong length= (ulong)(packet_end - next_packet);
|
||||||
|
|
||||||
log_slow_statement(thd);
|
log_slow_statement(thd);
|
||||||
@ -1336,12 +1330,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= "closing tables";
|
||||||
{
|
/* Free tables */
|
||||||
thd->proc_info="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,
|
||||||
@ -1355,9 +1348,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);
|
||||||
@ -3053,6 +3046,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;
|
||||||
@ -3930,7 +3927,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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4523,7 +4520,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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5467,7 +5464,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
|
||||||
@ -5491,7 +5488,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));
|
||||||
|
|
||||||
@ -6311,7 +6308,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,
|
||||||
@ -7274,10 +7271,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. */
|
||||||
|
|
||||||
|
@ -2864,7 +2864,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();
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
@ -817,7 +817,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"));
|
||||||
@ -826,7 +826,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"));
|
||||||
@ -1031,7 +1031,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"));
|
||||||
@ -1162,7 +1162,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"));
|
||||||
@ -1185,7 +1185,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"));
|
||||||
@ -2098,10 +2098,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;
|
||||||
@ -2307,7 +2307,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();
|
||||||
@ -2333,7 +2333,7 @@ err:
|
|||||||
{
|
{
|
||||||
thd->proc_info="end";
|
thd->proc_info="end";
|
||||||
err|= select_lex->cleanup();
|
err|= select_lex->cleanup();
|
||||||
DBUG_RETURN(err || thd->net.report_error);
|
DBUG_RETURN(err || thd->is_error());
|
||||||
}
|
}
|
||||||
DBUG_RETURN(join->error);
|
DBUG_RETURN(join->error);
|
||||||
}
|
}
|
||||||
@ -6651,7 +6651,14 @@ 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();
|
{
|
||||||
|
if (tab->table->key_read)
|
||||||
|
{
|
||||||
|
tab->table->key_read= 0;
|
||||||
|
tab->table->file->extra(HA_EXTRA_NO_KEYREAD);
|
||||||
|
}
|
||||||
|
tab->table->file->ha_index_or_rnd_end();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10710,7 +10717,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -10864,7 +10871,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)
|
||||||
@ -10896,13 +10902,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 &&
|
||||||
@ -10926,13 +10932,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;
|
||||||
@ -16043,7 +16049,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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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])))
|
||||||
|
@ -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 */
|
||||||
|
@ -607,7 +607,7 @@ err:
|
|||||||
thd->proc_info= "end";
|
thd->proc_info= "end";
|
||||||
lex->link_first_table_back(view, link_to_local);
|
lex->link_first_table_back(view, link_to_local);
|
||||||
unit->cleanup();
|
unit->cleanup();
|
||||||
DBUG_RETURN(res || thd->net.report_error);
|
DBUG_RETURN(res || thd->is_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -823,7 +823,7 @@ loop_out:
|
|||||||
view_parameters + revision_number_position, 1,
|
view_parameters + revision_number_position, 1,
|
||||||
&file_parser_dummy_hook))
|
&file_parser_dummy_hook))
|
||||||
{
|
{
|
||||||
error= thd->net.report_error? -1 : 0;
|
error= thd->is_error() ? -1 : 0;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -886,7 +886,7 @@ loop_out:
|
|||||||
if (sql_create_definition_file(&dir, &file, view_file_type,
|
if (sql_create_definition_file(&dir, &file, view_file_type,
|
||||||
(uchar*)view, view_parameters, num_view_backups))
|
(uchar*)view, view_parameters, num_view_backups))
|
||||||
{
|
{
|
||||||
error= thd->net.report_error? -1 : 1;
|
error= thd->is_error() ? -1 : 1;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
@ -9804,7 +9804,7 @@ NUM_literal:
|
|||||||
| DECIMAL_NUM
|
| DECIMAL_NUM
|
||||||
{
|
{
|
||||||
$$= new Item_decimal($1.str, $1.length, YYTHD->charset());
|
$$= new Item_decimal($1.str, $1.length, YYTHD->charset());
|
||||||
if (YYTHD->net.report_error)
|
if (YYTHD->is_error())
|
||||||
{
|
{
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
@ -9812,7 +9812,7 @@ NUM_literal:
|
|||||||
| FLOAT_NUM
|
| FLOAT_NUM
|
||||||
{
|
{
|
||||||
$$ = new Item_float($1.str, $1.length);
|
$$ = new Item_float($1.str, $1.length);
|
||||||
if (YYTHD->net.report_error)
|
if (YYTHD->is_error())
|
||||||
{
|
{
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
@ -10516,6 +10516,7 @@ set:
|
|||||||
lex->option_type=OPT_SESSION;
|
lex->option_type=OPT_SESSION;
|
||||||
lex->var_list.empty();
|
lex->var_list.empty();
|
||||||
lex->one_shot_set= 0;
|
lex->one_shot_set= 0;
|
||||||
|
lex->autocommit= 0;
|
||||||
}
|
}
|
||||||
option_value_list
|
option_value_list
|
||||||
{}
|
{}
|
||||||
@ -10558,6 +10559,7 @@ option_type_value:
|
|||||||
lex->option_type=OPT_SESSION;
|
lex->option_type=OPT_SESSION;
|
||||||
lex->var_list.empty();
|
lex->var_list.empty();
|
||||||
lex->one_shot_set= 0;
|
lex->one_shot_set= 0;
|
||||||
|
lex->autocommit= 0;
|
||||||
lex->sphead->m_tmp_query= lip->get_tok_start();
|
lex->sphead->m_tmp_query= lip->get_tok_start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10799,10 +10801,16 @@ option_value:
|
|||||||
user->host=null_lex_str;
|
user->host=null_lex_str;
|
||||||
user->user.str=thd->security_ctx->priv_user;
|
user->user.str=thd->security_ctx->priv_user;
|
||||||
thd->lex->var_list.push_back(new set_var_password(user, $3));
|
thd->lex->var_list.push_back(new set_var_password(user, $3));
|
||||||
|
thd->lex->autocommit= TRUE;
|
||||||
|
if (lex->sphead)
|
||||||
|
lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
|
||||||
}
|
}
|
||||||
| PASSWORD FOR_SYM user equal text_or_password
|
| PASSWORD FOR_SYM user equal text_or_password
|
||||||
{
|
{
|
||||||
Lex->var_list.push_back(new set_var_password($3,$5));
|
Lex->var_list.push_back(new set_var_password($3,$5));
|
||||||
|
Lex->autocommit= TRUE;
|
||||||
|
if (Lex->sphead)
|
||||||
|
Lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
22
sql/table.h
22
sql/table.h
@ -499,6 +499,24 @@ struct st_table {
|
|||||||
my_bitmap_map *bitmap_init_value;
|
my_bitmap_map *bitmap_init_value;
|
||||||
MY_BITMAP def_read_set, def_write_set, tmp_set; /* containers */
|
MY_BITMAP def_read_set, def_write_set, tmp_set; /* containers */
|
||||||
MY_BITMAP *read_set, *write_set; /* Active column sets */
|
MY_BITMAP *read_set, *write_set; /* Active column sets */
|
||||||
|
/*
|
||||||
|
The ID of the query that opened and is using this table. Has different
|
||||||
|
meanings depending on the table type.
|
||||||
|
|
||||||
|
Temporary tables:
|
||||||
|
|
||||||
|
table->query_id is set to thd->query_id for the duration of a statement
|
||||||
|
and is reset to 0 once it is closed by the same statement. A non-zero
|
||||||
|
table->query_id means that a statement is using the table even if it's
|
||||||
|
not the current statement (table is in use by some outer statement).
|
||||||
|
|
||||||
|
Non-temporary tables:
|
||||||
|
|
||||||
|
Under pre-locked or LOCK TABLES mode: query_id is set to thd->query_id
|
||||||
|
for the duration of a statement and is reset to 0 once it is closed by
|
||||||
|
the same statement. A non-zero query_id is used to control which tables
|
||||||
|
in the list of pre-opened and locked tables are actually being used.
|
||||||
|
*/
|
||||||
query_id_t query_id;
|
query_id_t query_id;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -593,8 +611,8 @@ struct st_table {
|
|||||||
my_bool locked_by_name;
|
my_bool locked_by_name;
|
||||||
my_bool fulltext_searched;
|
my_bool fulltext_searched;
|
||||||
my_bool no_cache;
|
my_bool no_cache;
|
||||||
/* To signal that we should reset query_id for tables and cols */
|
/* To signal that the table is associated with a HANDLER statement */
|
||||||
my_bool clear_query_id;
|
my_bool open_by_handler;
|
||||||
/*
|
/*
|
||||||
To indicate that a non-null value of the auto_increment field
|
To indicate that a non-null value of the auto_increment field
|
||||||
was provided by the user or retrieved from the current record.
|
was provided by the user or retrieved from the current record.
|
||||||
|
@ -47,6 +47,35 @@ static bool make_empty_rec(THD *thd, int file, enum legacy_db_type table_type,
|
|||||||
uint reclength, ulong data_offset,
|
uint reclength, ulong data_offset,
|
||||||
handler *handler);
|
handler *handler);
|
||||||
|
|
||||||
|
/**
|
||||||
|
An interceptor to hijack ER_TOO_MANY_FIELDS error from
|
||||||
|
pack_screens and retry again without UNIREG screens.
|
||||||
|
|
||||||
|
XXX: what is a UNIREG screen?
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct Pack_header_error_handler: public Internal_error_handler
|
||||||
|
{
|
||||||
|
virtual bool handle_error(uint sql_errno,
|
||||||
|
const char *message,
|
||||||
|
MYSQL_ERROR::enum_warning_level level,
|
||||||
|
THD *thd);
|
||||||
|
bool is_handled;
|
||||||
|
Pack_header_error_handler() :is_handled(FALSE) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Pack_header_error_handler::
|
||||||
|
handle_error(uint sql_errno,
|
||||||
|
const char * /* message */,
|
||||||
|
MYSQL_ERROR::enum_warning_level /* level */,
|
||||||
|
THD * /* thd */)
|
||||||
|
{
|
||||||
|
is_handled= (sql_errno == ER_TOO_MANY_FIELDS);
|
||||||
|
return is_handled;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create a frm (table definition) file
|
Create a frm (table definition) file
|
||||||
|
|
||||||
@ -86,6 +115,8 @@ bool mysql_create_frm(THD *thd, const char *file_name,
|
|||||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||||
partition_info *part_info= thd->work_part_info;
|
partition_info *part_info= thd->work_part_info;
|
||||||
#endif
|
#endif
|
||||||
|
Pack_header_error_handler pack_header_error_handler;
|
||||||
|
int error;
|
||||||
DBUG_ENTER("mysql_create_frm");
|
DBUG_ENTER("mysql_create_frm");
|
||||||
|
|
||||||
DBUG_ASSERT(*fn_rext((char*)file_name)); // Check .frm extension
|
DBUG_ASSERT(*fn_rext((char*)file_name)); // Check .frm extension
|
||||||
@ -99,17 +130,22 @@ bool mysql_create_frm(THD *thd, const char *file_name,
|
|||||||
create_info->null_bits++;
|
create_info->null_bits++;
|
||||||
data_offset= (create_info->null_bits + 7) / 8;
|
data_offset= (create_info->null_bits + 7) / 8;
|
||||||
|
|
||||||
if (pack_header(forminfo, ha_legacy_type(create_info->db_type),
|
thd->push_internal_handler(&pack_header_error_handler);
|
||||||
create_fields,info_length,
|
|
||||||
screens, create_info->table_options,
|
error= pack_header(forminfo, ha_legacy_type(create_info->db_type),
|
||||||
data_offset, db_file))
|
create_fields,info_length,
|
||||||
|
screens, create_info->table_options,
|
||||||
|
data_offset, db_file);
|
||||||
|
|
||||||
|
thd->pop_internal_handler();
|
||||||
|
|
||||||
|
if (error)
|
||||||
{
|
{
|
||||||
my_free(screen_buff, MYF(0));
|
my_free(screen_buff, MYF(0));
|
||||||
if (thd->net.last_errno != ER_TOO_MANY_FIELDS)
|
if (! pack_header_error_handler.is_handled)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
// Try again without UNIREG screens (to get more columns)
|
// Try again without UNIREG screens (to get more columns)
|
||||||
thd->net.last_error[0]=0;
|
|
||||||
if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,1)))
|
if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,1)))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
if (pack_header(forminfo, ha_legacy_type(create_info->db_type),
|
if (pack_header(forminfo, ha_legacy_type(create_info->db_type),
|
||||||
|
@ -17100,6 +17100,99 @@ static void test_bug31418()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Bug#31669 Buffer overflow in mysql_change_user()
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LARGE_BUFFER_SIZE 2048
|
||||||
|
|
||||||
|
static void test_bug31669()
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
static char buff[LARGE_BUFFER_SIZE+1];
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
static char user[USERNAME_CHAR_LENGTH+1];
|
||||||
|
static char db[NAME_CHAR_LEN+1];
|
||||||
|
static char query[LARGE_BUFFER_SIZE*2];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DBUG_ENTER("test_bug31669");
|
||||||
|
myheader("test_bug31669");
|
||||||
|
|
||||||
|
rc= mysql_change_user(mysql, NULL, NULL, NULL);
|
||||||
|
DIE_UNLESS(rc);
|
||||||
|
|
||||||
|
rc= mysql_change_user(mysql, "", "", "");
|
||||||
|
DIE_UNLESS(rc);
|
||||||
|
|
||||||
|
memset(buff, 'a', sizeof(buff));
|
||||||
|
|
||||||
|
rc= mysql_change_user(mysql, buff, buff, buff);
|
||||||
|
DIE_UNLESS(rc);
|
||||||
|
|
||||||
|
rc = mysql_change_user(mysql, opt_user, opt_password, current_db);
|
||||||
|
DIE_UNLESS(!rc);
|
||||||
|
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
memset(db, 'a', sizeof(db));
|
||||||
|
db[NAME_CHAR_LEN]= 0;
|
||||||
|
strxmov(query, "CREATE DATABASE IF NOT EXISTS ", db, NullS);
|
||||||
|
rc= mysql_query(mysql, query);
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
memset(user, 'b', sizeof(user));
|
||||||
|
user[USERNAME_CHAR_LENGTH]= 0;
|
||||||
|
memset(buff, 'c', sizeof(buff));
|
||||||
|
buff[LARGE_BUFFER_SIZE]= 0;
|
||||||
|
strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'%' IDENTIFIED BY "
|
||||||
|
"'", buff, "' WITH GRANT OPTION", NullS);
|
||||||
|
rc= mysql_query(mysql, query);
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "FLUSH PRIVILEGES");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_change_user(mysql, user, buff, db);
|
||||||
|
DIE_UNLESS(!rc);
|
||||||
|
|
||||||
|
user[USERNAME_CHAR_LENGTH-1]= 'a';
|
||||||
|
rc= mysql_change_user(mysql, user, buff, db);
|
||||||
|
DIE_UNLESS(rc);
|
||||||
|
|
||||||
|
user[USERNAME_CHAR_LENGTH-1]= 'b';
|
||||||
|
buff[LARGE_BUFFER_SIZE-1]= 'd';
|
||||||
|
rc= mysql_change_user(mysql, user, buff, db);
|
||||||
|
DIE_UNLESS(rc);
|
||||||
|
|
||||||
|
buff[LARGE_BUFFER_SIZE-1]= 'c';
|
||||||
|
db[NAME_CHAR_LEN-1]= 'e';
|
||||||
|
rc= mysql_change_user(mysql, user, buff, db);
|
||||||
|
DIE_UNLESS(rc);
|
||||||
|
|
||||||
|
db[NAME_CHAR_LEN-1]= 'a';
|
||||||
|
rc= mysql_change_user(mysql, user, buff, db);
|
||||||
|
DIE_UNLESS(!rc);
|
||||||
|
|
||||||
|
rc= mysql_change_user(mysql, user + 1, buff + 1, db + 1);
|
||||||
|
DIE_UNLESS(rc);
|
||||||
|
|
||||||
|
rc = mysql_change_user(mysql, opt_user, opt_password, current_db);
|
||||||
|
DIE_UNLESS(!rc);
|
||||||
|
|
||||||
|
strxmov(query, "DROP DATABASE ", db, NullS);
|
||||||
|
rc= mysql_query(mysql, query);
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
strxmov(query, "DELETE FROM mysql.user WHERE User='", user, "'", NullS);
|
||||||
|
rc= mysql_query(mysql, query);
|
||||||
|
myquery(rc);
|
||||||
|
DIE_UNLESS(mysql_affected_rows(mysql) == 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read and parse arguments and MySQL options from my.cnf
|
Read and parse arguments and MySQL options from my.cnf
|
||||||
*/
|
*/
|
||||||
@ -17403,6 +17496,7 @@ static struct my_tests_st my_tests[]= {
|
|||||||
{ "test_bug30472", test_bug30472 },
|
{ "test_bug30472", test_bug30472 },
|
||||||
{ "test_bug20023", test_bug20023 },
|
{ "test_bug20023", test_bug20023 },
|
||||||
{ "test_bug31418", test_bug31418 },
|
{ "test_bug31418", test_bug31418 },
|
||||||
|
{ "test_bug31669", test_bug31669 },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user