Loading mysql-test/r/ps.result +1 −0 Original line number Diff line number Diff line Loading @@ -1475,4 +1475,5 @@ i 1 DEALLOCATE PREPARE stmt; DROP TABLE t1, t2; DROP PROCEDURE IF EXISTS p1; End of 5.0 tests. mysql-test/t/ps.test +20 −0 Original line number Diff line number Diff line Loading @@ -1513,4 +1513,24 @@ DEALLOCATE PREPARE stmt; 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. sql/sql_parse.cc +7 −2 Original line number Diff line number Diff line Loading @@ -5878,14 +5878,19 @@ void mysql_parse(THD *thd, char *inBuf, uint length) DBUG_ASSERT(thd->net.report_error); DBUG_PRINT("info",("Command aborted. Fatal_error: %d", 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) { /* Clean up after failed stored procedure/function */ delete thd->lex->sphead; thd->lex->sphead= NULL; } query_cache_abort(&thd->net); lex->unit.cleanup(); } thd->proc_info="freeing items"; thd->end_statement(); Loading sql/sql_prepare.cc +11 −0 Original line number Diff line number Diff line Loading @@ -2773,6 +2773,16 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) error= MYSQLparse((void *)thd) || thd->is_fatal_error || 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) we allocate a lot of additional memory: for open tables, JOINs, derived Loading @@ -2798,6 +2808,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) if (error == 0) error= check_prepared_statement(this, name.str != 0); /* Free sp_head if check_prepared_statement() failed. */ if (error && lex->sphead) { delete lex->sphead; Loading Loading
mysql-test/r/ps.result +1 −0 Original line number Diff line number Diff line Loading @@ -1475,4 +1475,5 @@ i 1 DEALLOCATE PREPARE stmt; DROP TABLE t1, t2; DROP PROCEDURE IF EXISTS p1; End of 5.0 tests.
mysql-test/t/ps.test +20 −0 Original line number Diff line number Diff line Loading @@ -1513,4 +1513,24 @@ DEALLOCATE PREPARE stmt; 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.
sql/sql_parse.cc +7 −2 Original line number Diff line number Diff line Loading @@ -5878,14 +5878,19 @@ void mysql_parse(THD *thd, char *inBuf, uint length) DBUG_ASSERT(thd->net.report_error); DBUG_PRINT("info",("Command aborted. Fatal_error: %d", 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) { /* Clean up after failed stored procedure/function */ delete thd->lex->sphead; thd->lex->sphead= NULL; } query_cache_abort(&thd->net); lex->unit.cleanup(); } thd->proc_info="freeing items"; thd->end_statement(); Loading
sql/sql_prepare.cc +11 −0 Original line number Diff line number Diff line Loading @@ -2773,6 +2773,16 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) error= MYSQLparse((void *)thd) || thd->is_fatal_error || 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) we allocate a lot of additional memory: for open tables, JOINs, derived Loading @@ -2798,6 +2808,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) if (error == 0) error= check_prepared_statement(this, name.str != 0); /* Free sp_head if check_prepared_statement() failed. */ if (error && lex->sphead) { delete lex->sphead; Loading