Commit f9b9c890 authored by unknown's avatar unknown

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

into  moonlight.intranet:/home/tomash/src/mysql_ab/mysql-5.1-bug21856


sql/sql_parse.cc:
  Auto merged
mysql-test/r/ps.result:
  Manual merge.
mysql-test/t/ps.test:
  Manual merge.
sql/sql_prepare.cc:
  Manual merge.
parents 4811d29f ef2d2165
...@@ -1456,6 +1456,7 @@ i ...@@ -1456,6 +1456,7 @@ 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.
create procedure proc_1() reset query cache; create procedure proc_1() reset query cache;
call proc_1(); call proc_1();
......
...@@ -1510,6 +1510,26 @@ DEALLOCATE PREPARE stmt; ...@@ -1510,6 +1510,26 @@ 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.
# #
......
...@@ -6088,14 +6088,19 @@ void mysql_parse(THD *thd, char *inBuf, uint length) ...@@ -6088,14 +6088,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 (lex->sphead) if (lex->sphead)
{ {
/* Clean up after failed stored procedure/function */ /* Clean up after failed stored procedure/function */
delete lex->sphead; delete lex->sphead;
lex->sphead= NULL; 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();
......
...@@ -2811,7 +2811,19 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) ...@@ -2811,7 +2811,19 @@ 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;
}
lex->safe_to_cache_query= FALSE; lex->safe_to_cache_query= FALSE;
/* /*
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
...@@ -2837,6 +2849,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) ...@@ -2837,6 +2849,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