summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkroki/tomash@moonlight.intranet <>2006-10-19 14:53:50 +0400
committerkroki/tomash@moonlight.intranet <>2006-10-19 14:53:50 +0400
commitdea0028cd951fc6fb2b898842e8f304bcfc6c532 (patch)
tree17801a185c97a76e7eee2ff2cc6f587503a36f5d
parent9fd2c861038facb19b9dc8df3c0c645915a6f407 (diff)
parent00b2fc6affe6ffcef7f50c77b1fb2cbc3116560b (diff)
downloadmariadb-git-dea0028cd951fc6fb2b898842e8f304bcfc6c532.tar.gz
Merge moonlight.intranet:/home/tomash/src/mysql_ab/mysql-5.0
into moonlight.intranet:/home/tomash/src/mysql_ab/mysql-5.0-bug21856
-rw-r--r--mysql-test/r/ps.result1
-rw-r--r--mysql-test/t/ps.test20
-rw-r--r--sql/sql_parse.cc9
-rw-r--r--sql/sql_prepare.cc11
4 files changed, 39 insertions, 2 deletions
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index da58b6b96ff..fe4ed785136 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -1475,4 +1475,5 @@ i
1
DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2;
+DROP PROCEDURE IF EXISTS p1;
End of 5.0 tests.
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 93dc6d86a85..a5734c7e6dc 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -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.
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index c62c286cfdb..7b5387e5e2f 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -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();
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 32f0ca6859d..fcbf495463a 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -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
@@ -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;