Commit dea0028c authored by kroki/tomash@moonlight.intranet's avatar kroki/tomash@moonlight.intranet

Merge moonlight.intranet:/home/tomash/src/mysql_ab/mysql-5.0

into  moonlight.intranet:/home/tomash/src/mysql_ab/mysql-5.0-bug21856
parents 9fd2c861 00b2fc6a
...@@ -1475,4 +1475,5 @@ i ...@@ -1475,4 +1475,5 @@ i
1 1
DEALLOCATE PREPARE stmt; DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2; DROP TABLE t1, t2;
DROP PROCEDURE IF EXISTS p1;
End of 5.0 tests. End of 5.0 tests.
...@@ -1513,4 +1513,24 @@ DEALLOCATE PREPARE stmt; ...@@ -1513,4 +1513,24 @@ DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2; DROP TABLE t1, t2;
#
# BUG#21856: Prepared Statments: crash if bad create
#
--disable_warnings
DROP PROCEDURE IF EXISTS p1;
--enable_warnings
let $iterations= 100;
--disable_query_log
--disable_result_log
while ($iterations > 0)
{
--error ER_PARSE_ERROR
PREPARE stmt FROM "CREATE PROCEDURE p1()";
dec $iterations;
}
--enable_query_log
--enable_result_log
--echo End of 5.0 tests. --echo End of 5.0 tests.
...@@ -5878,14 +5878,19 @@ void mysql_parse(THD *thd, char *inBuf, uint length) ...@@ -5878,14 +5878,19 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
DBUG_ASSERT(thd->net.report_error); DBUG_ASSERT(thd->net.report_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));
query_cache_abort(&thd->net);
lex->unit.cleanup(); /*
The first thing we do after parse error is freeing sp_head to
ensure that we have restored original memroot.
*/
if (thd->lex->sphead) if (thd->lex->sphead)
{ {
/* Clean up after failed stored procedure/function */ /* Clean up after failed stored procedure/function */
delete thd->lex->sphead; delete thd->lex->sphead;
thd->lex->sphead= NULL; thd->lex->sphead= NULL;
} }
query_cache_abort(&thd->net);
lex->unit.cleanup();
} }
thd->proc_info="freeing items"; thd->proc_info="freeing items";
thd->end_statement(); thd->end_statement();
......
...@@ -2773,6 +2773,16 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) ...@@ -2773,6 +2773,16 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
error= MYSQLparse((void *)thd) || thd->is_fatal_error || error= MYSQLparse((void *)thd) || thd->is_fatal_error ||
thd->net.report_error || init_param_array(this); thd->net.report_error || init_param_array(this);
/*
The first thing we do after parse error is freeing sp_head to
ensure that we have restored original memroot.
*/
if (error && lex->sphead)
{
delete lex->sphead;
lex->sphead= NULL;
}
/* /*
While doing context analysis of the query (in check_prepared_statement) While doing context analysis of the query (in check_prepared_statement)
we allocate a lot of additional memory: for open tables, JOINs, derived we allocate a lot of additional memory: for open tables, JOINs, derived
...@@ -2798,6 +2808,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) ...@@ -2798,6 +2808,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
if (error == 0) if (error == 0)
error= check_prepared_statement(this, name.str != 0); error= check_prepared_statement(this, name.str != 0);
/* Free sp_head if check_prepared_statement() failed. */
if (error && lex->sphead) if (error && lex->sphead)
{ {
delete lex->sphead; delete lex->sphead;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment