Manual merge from the bugfix tree.
conflicts: conflict sql/sql_parse.cc
This commit is contained in:
commit
e5cf56ef80
@ -39,5 +39,14 @@ a
|
|||||||
2
|
2
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# Bug#42064: low memory crash when importing hex strings, in Item_hex_string::Item_hex_string
|
||||||
|
#
|
||||||
|
CREATE TABLE t1(a BLOB);
|
||||||
|
SET SESSION debug="+d,bug42064_simulate_oom";
|
||||||
|
INSERT INTO t1 VALUES("");
|
||||||
|
Got one of the listed errors
|
||||||
|
SET SESSION debug=DEFAULT;
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 5.1 tests
|
# End of 5.1 tests
|
||||||
#
|
#
|
||||||
|
@ -46,6 +46,20 @@ SELECT * FROM t1;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#42064: low memory crash when importing hex strings, in Item_hex_string::Item_hex_string
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1(a BLOB);
|
||||||
|
|
||||||
|
SET SESSION debug="+d,bug42064_simulate_oom";
|
||||||
|
# May fail with either ER_OUT_OF_RESOURCES or EE_OUTOFMEMORY
|
||||||
|
--error ER_OUT_OF_RESOURCES, 5
|
||||||
|
INSERT INTO t1 VALUES("");
|
||||||
|
SET SESSION debug=DEFAULT;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 5.1 tests
|
--echo # End of 5.1 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -154,6 +154,14 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
|
|||||||
|
|
||||||
DBUG_ASSERT(alloc_root_inited(mem_root));
|
DBUG_ASSERT(alloc_root_inited(mem_root));
|
||||||
|
|
||||||
|
DBUG_EXECUTE_IF("simulate_out_of_memory",
|
||||||
|
{
|
||||||
|
if (mem_root->error_handler)
|
||||||
|
(*mem_root->error_handler)();
|
||||||
|
DBUG_SET("-d,simulate_out_of_memory");
|
||||||
|
DBUG_RETURN((void*) 0); /* purecov: inspected */
|
||||||
|
});
|
||||||
|
|
||||||
length+=ALIGN_SIZE(sizeof(USED_MEM));
|
length+=ALIGN_SIZE(sizeof(USED_MEM));
|
||||||
if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME))))
|
if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME))))
|
||||||
{
|
{
|
||||||
@ -176,6 +184,14 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
|
|||||||
DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root));
|
DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root));
|
||||||
DBUG_ASSERT(alloc_root_inited(mem_root));
|
DBUG_ASSERT(alloc_root_inited(mem_root));
|
||||||
|
|
||||||
|
DBUG_EXECUTE_IF("simulate_out_of_memory",
|
||||||
|
{
|
||||||
|
/* Avoid reusing an already allocated block */
|
||||||
|
if (mem_root->error_handler)
|
||||||
|
(*mem_root->error_handler)();
|
||||||
|
DBUG_SET("-d,simulate_out_of_memory");
|
||||||
|
DBUG_RETURN((void*) 0); /* purecov: inspected */
|
||||||
|
});
|
||||||
length= ALIGN_SIZE(length);
|
length= ALIGN_SIZE(length);
|
||||||
if ((*(prev= &mem_root->free)) != NULL)
|
if ((*(prev= &mem_root->free)) != NULL)
|
||||||
{
|
{
|
||||||
|
@ -31,13 +31,23 @@ void *my_malloc(size_t size, myf my_flags)
|
|||||||
|
|
||||||
if (!size)
|
if (!size)
|
||||||
size=1; /* Safety */
|
size=1; /* Safety */
|
||||||
if ((point = (char*)malloc(size)) == NULL)
|
|
||||||
|
point= (char *) malloc(size);
|
||||||
|
DBUG_EXECUTE_IF("simulate_out_of_memory",
|
||||||
|
{
|
||||||
|
free(point);
|
||||||
|
point= NULL;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (point == NULL)
|
||||||
{
|
{
|
||||||
my_errno=errno;
|
my_errno=errno;
|
||||||
if (my_flags & MY_FAE)
|
if (my_flags & MY_FAE)
|
||||||
error_handler_hook=fatal_error_handler_hook;
|
error_handler_hook=fatal_error_handler_hook;
|
||||||
if (my_flags & (MY_FAE+MY_WME))
|
if (my_flags & (MY_FAE+MY_WME))
|
||||||
my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG+ME_NOREFRESH),size);
|
my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG+ME_NOREFRESH),size);
|
||||||
|
DBUG_EXECUTE_IF("simulate_out_of_memory",
|
||||||
|
DBUG_SET("-d,simulate_out_of_memory"););
|
||||||
if (my_flags & MY_FAE)
|
if (my_flags & MY_FAE)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -139,6 +139,11 @@ void *_mymalloc(size_t size, const char *filename, uint lineno, myf MyFlags)
|
|||||||
size + /* size requested */
|
size + /* size requested */
|
||||||
4 + /* overrun mark */
|
4 + /* overrun mark */
|
||||||
sf_malloc_endhunc);
|
sf_malloc_endhunc);
|
||||||
|
DBUG_EXECUTE_IF("simulate_out_of_memory",
|
||||||
|
{
|
||||||
|
free(irem);
|
||||||
|
irem= NULL;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
/* Check if there isn't anymore memory avaiable */
|
/* Check if there isn't anymore memory avaiable */
|
||||||
if (!irem)
|
if (!irem)
|
||||||
@ -159,6 +164,8 @@ void *_mymalloc(size_t size, const char *filename, uint lineno, myf MyFlags)
|
|||||||
}
|
}
|
||||||
DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'",
|
DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'",
|
||||||
sf_malloc_max_memory,lineno, filename));
|
sf_malloc_max_memory,lineno, filename));
|
||||||
|
DBUG_EXECUTE_IF("simulate_out_of_memory",
|
||||||
|
DBUG_SET("-d,simulate_out_of_memory"););
|
||||||
if (MyFlags & MY_FAE)
|
if (MyFlags & MY_FAE)
|
||||||
exit(1);
|
exit(1);
|
||||||
DBUG_RETURN ((void*) 0);
|
DBUG_RETURN ((void*) 0);
|
||||||
|
@ -1434,7 +1434,10 @@ Event_job_data::execute(THD *thd, bool drop)
|
|||||||
thd->set_query(sp_sql.c_ptr_safe(), sp_sql.length());
|
thd->set_query(sp_sql.c_ptr_safe(), sp_sql.length());
|
||||||
|
|
||||||
{
|
{
|
||||||
Parser_state parser_state(thd, thd->query(), thd->query_length());
|
Parser_state parser_state;
|
||||||
|
if (parser_state.init(thd, thd->query(), thd->query_length()))
|
||||||
|
goto end;
|
||||||
|
|
||||||
lex_start(thd);
|
lex_start(thd);
|
||||||
|
|
||||||
if (parse_sql(thd, & parser_state, creation_ctx))
|
if (parse_sql(thd, & parser_state, creation_ctx))
|
||||||
|
@ -2967,6 +2967,9 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* When simulating OOM, skip writing to error log to avoid mtr errors */
|
||||||
|
DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(0););
|
||||||
|
|
||||||
if (!thd->no_warnings_for_error &&
|
if (!thd->no_warnings_for_error &&
|
||||||
!(MyFlags & ME_NO_WARNING_FOR_ERROR))
|
!(MyFlags & ME_NO_WARNING_FOR_ERROR))
|
||||||
{
|
{
|
||||||
@ -2979,6 +2982,10 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
|
|||||||
thd->no_warnings_for_error= FALSE;
|
thd->no_warnings_for_error= FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* When simulating OOM, skip writing to error log to avoid mtr errors */
|
||||||
|
DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(0););
|
||||||
|
|
||||||
if (!thd || MyFlags & ME_NOREFRESH)
|
if (!thd || MyFlags & ME_NOREFRESH)
|
||||||
sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */
|
sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
@ -782,7 +782,12 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
|
|||||||
thd->spcont= NULL;
|
thd->spcont= NULL;
|
||||||
|
|
||||||
{
|
{
|
||||||
Parser_state parser_state(thd, defstr.c_ptr(), defstr.length());
|
Parser_state parser_state;
|
||||||
|
if (parser_state.init(thd, defstr.c_ptr(), defstr.length()))
|
||||||
|
{
|
||||||
|
ret= SP_INTERNAL_ERROR;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
lex_start(thd);
|
lex_start(thd);
|
||||||
|
|
||||||
|
@ -110,39 +110,31 @@ st_parsing_options::reset()
|
|||||||
allows_derived= TRUE;
|
allows_derived= TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lex_input_stream::Lex_input_stream(THD *thd,
|
|
||||||
const char* buffer,
|
|
||||||
unsigned int length)
|
|
||||||
: m_thd(thd),
|
|
||||||
yylineno(1),
|
|
||||||
yytoklen(0),
|
|
||||||
yylval(NULL),
|
|
||||||
m_ptr(buffer),
|
|
||||||
m_tok_start(NULL),
|
|
||||||
m_tok_end(NULL),
|
|
||||||
m_end_of_query(buffer + length),
|
|
||||||
m_tok_start_prev(NULL),
|
|
||||||
m_buf(buffer),
|
|
||||||
m_buf_length(length),
|
|
||||||
m_echo(TRUE),
|
|
||||||
m_cpp_tok_start(NULL),
|
|
||||||
m_cpp_tok_start_prev(NULL),
|
|
||||||
m_cpp_tok_end(NULL),
|
|
||||||
m_body_utf8(NULL),
|
|
||||||
m_cpp_utf8_processed_ptr(NULL),
|
|
||||||
next_state(MY_LEX_START),
|
|
||||||
found_semicolon(NULL),
|
|
||||||
ignore_space(test(thd->variables.sql_mode & MODE_IGNORE_SPACE)),
|
|
||||||
stmt_prepare_mode(FALSE),
|
|
||||||
in_comment(NO_COMMENT),
|
|
||||||
m_underscore_cs(NULL)
|
|
||||||
{
|
|
||||||
m_cpp_buf= (char*) thd->alloc(length + 1);
|
|
||||||
m_cpp_ptr= m_cpp_buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
Lex_input_stream::~Lex_input_stream()
|
bool Lex_input_stream::init(THD *thd, const char *buff, unsigned int length)
|
||||||
{}
|
{
|
||||||
|
DBUG_EXECUTE_IF("bug42064_simulate_oom",
|
||||||
|
DBUG_SET("+d,simulate_out_of_memory"););
|
||||||
|
|
||||||
|
m_cpp_buf= (char*) thd->alloc(length + 1);
|
||||||
|
|
||||||
|
DBUG_EXECUTE_IF("bug42064_simulate_oom",
|
||||||
|
DBUG_SET("-d,bug42064_simulate_oom"););
|
||||||
|
|
||||||
|
if (m_cpp_buf == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
m_cpp_ptr= m_cpp_buf;
|
||||||
|
m_thd= thd;
|
||||||
|
m_ptr= buff;
|
||||||
|
m_end_of_query= buff + length;
|
||||||
|
m_buf= buff;
|
||||||
|
m_buf_length= length;
|
||||||
|
ignore_space= test(thd->variables.sql_mode & MODE_IGNORE_SPACE);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The operation is called from the parser in order to
|
The operation is called from the parser in order to
|
||||||
|
@ -1149,9 +1149,38 @@ enum enum_comment_state
|
|||||||
class Lex_input_stream
|
class Lex_input_stream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Lex_input_stream(THD *thd, const char* buff, unsigned int length);
|
Lex_input_stream() :
|
||||||
~Lex_input_stream();
|
yylineno(1),
|
||||||
|
yytoklen(0),
|
||||||
|
yylval(NULL),
|
||||||
|
m_tok_start(NULL),
|
||||||
|
m_tok_end(NULL),
|
||||||
|
m_tok_start_prev(NULL),
|
||||||
|
m_echo(TRUE),
|
||||||
|
m_cpp_tok_start(NULL),
|
||||||
|
m_cpp_tok_start_prev(NULL),
|
||||||
|
m_cpp_tok_end(NULL),
|
||||||
|
m_body_utf8(NULL),
|
||||||
|
m_cpp_utf8_processed_ptr(NULL),
|
||||||
|
next_state(MY_LEX_START),
|
||||||
|
found_semicolon(NULL),
|
||||||
|
stmt_prepare_mode(FALSE),
|
||||||
|
in_comment(NO_COMMENT),
|
||||||
|
m_underscore_cs(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~Lex_input_stream()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Object initializer. Must be called before usage.
|
||||||
|
|
||||||
|
@retval FALSE OK
|
||||||
|
@retval TRUE Error
|
||||||
|
*/
|
||||||
|
bool init(THD *thd, const char *buff, unsigned int length);
|
||||||
/**
|
/**
|
||||||
Set the echo mode.
|
Set the echo mode.
|
||||||
|
|
||||||
@ -1933,10 +1962,21 @@ public:
|
|||||||
class Parser_state
|
class Parser_state
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Parser_state(THD *thd, const char* buff, unsigned int length)
|
Parser_state()
|
||||||
: m_lip(thd, buff, length), m_yacc()
|
: m_yacc()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Object initializer. Must be called before usage.
|
||||||
|
|
||||||
|
@retval FALSE OK
|
||||||
|
@retval TRUE Error
|
||||||
|
*/
|
||||||
|
bool init(THD *thd, const char *buff, unsigned int length)
|
||||||
|
{
|
||||||
|
return m_lip.init(thd, buff, length);
|
||||||
|
}
|
||||||
|
|
||||||
~Parser_state()
|
~Parser_state()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -5966,10 +5966,15 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
|
|||||||
sp_cache_flush_obsolete(&thd->sp_proc_cache);
|
sp_cache_flush_obsolete(&thd->sp_proc_cache);
|
||||||
sp_cache_flush_obsolete(&thd->sp_func_cache);
|
sp_cache_flush_obsolete(&thd->sp_func_cache);
|
||||||
|
|
||||||
Parser_state parser_state(thd, inBuf, length);
|
Parser_state parser_state;
|
||||||
|
bool err;
|
||||||
bool err= parse_sql(thd, & parser_state, NULL);
|
if (!(err= parser_state.init(thd, inBuf, length)))
|
||||||
*found_semicolon= parser_state.m_lip.found_semicolon;
|
{
|
||||||
|
err= parse_sql(thd, & parser_state, NULL);
|
||||||
|
*found_semicolon= parser_state.m_lip.found_semicolon;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*found_semicolon= NULL;
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
{
|
{
|
||||||
@ -6055,14 +6060,17 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
|
|||||||
bool error= 0;
|
bool error= 0;
|
||||||
DBUG_ENTER("mysql_test_parse_for_slave");
|
DBUG_ENTER("mysql_test_parse_for_slave");
|
||||||
|
|
||||||
Parser_state parser_state(thd, inBuf, length);
|
Parser_state parser_state;
|
||||||
lex_start(thd);
|
if (!(error= parser_state.init(thd, inBuf, length)))
|
||||||
mysql_reset_thd_for_next_command(thd);
|
{
|
||||||
|
lex_start(thd);
|
||||||
|
mysql_reset_thd_for_next_command(thd);
|
||||||
|
|
||||||
if (!parse_sql(thd, & parser_state, NULL) &&
|
if (!parse_sql(thd, & parser_state, NULL) &&
|
||||||
all_tables_not_ok(thd, lex->select_lex.table_list.first))
|
all_tables_not_ok(thd, lex->select_lex.table_list.first))
|
||||||
error= 1; /* Ignore question */
|
error= 1; /* Ignore question */
|
||||||
thd->end_statement();
|
thd->end_statement();
|
||||||
|
}
|
||||||
thd->cleanup_after_query();
|
thd->cleanup_after_query();
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
@ -3892,7 +3892,9 @@ bool mysql_unpack_partition(THD *thd,
|
|||||||
thd->lex= &lex;
|
thd->lex= &lex;
|
||||||
thd->variables.character_set_client= system_charset_info;
|
thd->variables.character_set_client= system_charset_info;
|
||||||
|
|
||||||
Parser_state parser_state(thd, part_buf, part_info_len);
|
Parser_state parser_state;
|
||||||
|
if (parser_state.init(thd, part_buf, part_info_len))
|
||||||
|
goto end;
|
||||||
|
|
||||||
lex_start(thd);
|
lex_start(thd);
|
||||||
*work_part_info_used= false;
|
*work_part_info_used= false;
|
||||||
|
@ -3033,13 +3033,16 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
|||||||
old_stmt_arena= thd->stmt_arena;
|
old_stmt_arena= thd->stmt_arena;
|
||||||
thd->stmt_arena= this;
|
thd->stmt_arena= this;
|
||||||
|
|
||||||
Parser_state parser_state(thd, thd->query(), thd->query_length());
|
Parser_state parser_state;
|
||||||
parser_state.m_lip.stmt_prepare_mode= TRUE;
|
if (!parser_state.init(thd, thd->query(), thd->query_length()))
|
||||||
lex_start(thd);
|
{
|
||||||
|
parser_state.m_lip.stmt_prepare_mode= TRUE;
|
||||||
|
lex_start(thd);
|
||||||
|
|
||||||
error= parse_sql(thd, & parser_state, NULL) ||
|
error= parse_sql(thd, & parser_state, NULL) ||
|
||||||
thd->is_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();
|
||||||
|
|
||||||
|
@ -1297,9 +1297,9 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
|
|||||||
|
|
||||||
thd->variables.sql_mode= (ulong)*trg_sql_mode;
|
thd->variables.sql_mode= (ulong)*trg_sql_mode;
|
||||||
|
|
||||||
Parser_state parser_state(thd,
|
Parser_state parser_state;
|
||||||
trg_create_str->str,
|
if (parser_state.init(thd, trg_create_str->str, trg_create_str->length))
|
||||||
trg_create_str->length);
|
goto err_with_lex_cleanup;
|
||||||
|
|
||||||
Trigger_creation_ctx *creation_ctx=
|
Trigger_creation_ctx *creation_ctx=
|
||||||
Trigger_creation_ctx::create(thd,
|
Trigger_creation_ctx::create(thd,
|
||||||
|
@ -1190,9 +1190,10 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
|
|||||||
char old_db_buf[NAME_LEN+1];
|
char old_db_buf[NAME_LEN+1];
|
||||||
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
|
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
|
||||||
bool dbchanged;
|
bool dbchanged;
|
||||||
Parser_state parser_state(thd,
|
Parser_state parser_state;
|
||||||
table->select_stmt.str,
|
if (parser_state.init(thd, table->select_stmt.str,
|
||||||
table->select_stmt.length);
|
table->select_stmt.length))
|
||||||
|
goto err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Use view db name as thread default database, in order to ensure
|
Use view db name as thread default database, in order to ensure
|
||||||
|
@ -21,8 +21,6 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
void sql_alloc_error_handler(void)
|
void sql_alloc_error_handler(void)
|
||||||
{
|
{
|
||||||
sql_print_error("%s", ER(ER_OUT_OF_RESOURCES));
|
|
||||||
|
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
if (thd)
|
if (thd)
|
||||||
{
|
{
|
||||||
@ -49,6 +47,12 @@ extern "C" {
|
|||||||
ER(ER_OUT_OF_RESOURCES));
|
ER(ER_OUT_OF_RESOURCES));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Skip writing to the error log to avoid mtr complaints */
|
||||||
|
DBUG_EXECUTE_IF("simulate_out_of_memory", return;);
|
||||||
|
|
||||||
|
sql_print_error("%s", ER(ER_OUT_OF_RESOURCES));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user