diff options
-rw-r--r-- | mysql-test/r/trigger.result | 23 | ||||
-rw-r--r-- | mysql-test/t/trigger.test | 31 | ||||
-rw-r--r-- | sql/sp_head.cc | 34 | ||||
-rw-r--r-- | sql/sp_head.h | 4 | ||||
-rw-r--r-- | sql/sql_lex.cc | 1 |
5 files changed, 68 insertions, 25 deletions
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index 3446babbb52..e3c0b0e1dd9 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -2128,4 +2128,27 @@ Warning 1048 Column 'id' cannot be null Warning 1048 Column 'id' cannot be null DROP TRIGGER t1_bu; DROP TABLE t1,t2; +# +# Bug#50755: Crash if stored routine def contains version comments +# +DROP DATABASE IF EXISTS db1; +DROP TRIGGER IF EXISTS trg1; +DROP TABLE IF EXISTS t1, t2; +CREATE DATABASE db1; +USE db1; +CREATE TABLE t1 (b INT); +CREATE TABLE t2 (a INT); +CREATE TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERT/*!INTO*/t1 VALUES (1); +# Used to crash +SHOW TRIGGERS IN db1; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +Warnings: +Warning 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES (1)' at line 1 +INSERT INTO t2 VALUES (1); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES (1)' at line 1 +SELECT * FROM t1; +b +# Work around Bug#45235 +DROP DATABASE db1; +USE test; End of 5.1 tests. diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test index 368271f1fb2..bcbca4d2139 100644 --- a/mysql-test/t/trigger.test +++ b/mysql-test/t/trigger.test @@ -2439,4 +2439,35 @@ UPDATE t1 SET id=NULL; DROP TRIGGER t1_bu; DROP TABLE t1,t2; +--echo # +--echo # Bug#50755: Crash if stored routine def contains version comments +--echo # + +--disable_warnings +DROP DATABASE IF EXISTS db1; +DROP TRIGGER IF EXISTS trg1; +DROP TABLE IF EXISTS t1, t2; +--enable_warnings + +CREATE DATABASE db1; +USE db1; + +CREATE TABLE t1 (b INT); +CREATE TABLE t2 (a INT); + +CREATE TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERT/*!INTO*/t1 VALUES (1); +--echo # Used to crash +SHOW TRIGGERS IN db1; +--error ER_PARSE_ERROR +INSERT INTO t2 VALUES (1); +SELECT * FROM t1; + +--echo # Work around Bug#45235 +let $MYSQLD_DATADIR = `select @@datadir`; +--remove_file $MYSQLD_DATADIR/db1/t2.TRG +--remove_file $MYSQLD_DATADIR/db1/trg1.TRN + +DROP DATABASE db1; +USE test; + --echo End of 5.1 tests. diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 11d5e5f830b..cadda38053c 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -745,21 +745,12 @@ sp_head::create(THD *thd) sp_head::~sp_head() { + LEX *lex; + sp_instr *i; DBUG_ENTER("sp_head::~sp_head"); - destroy(); - delete m_next_cached_sp; - if (m_thd) - restore_thd_mem_root(m_thd); - DBUG_VOID_RETURN; -} -void -sp_head::destroy() -{ - sp_instr *i; - LEX *lex; - DBUG_ENTER("sp_head::destroy"); - DBUG_PRINT("info", ("name: %s", m_name.str)); + /* sp_head::restore_thd_mem_root() must already have been called. */ + DBUG_ASSERT(m_thd == NULL); for (uint ip = 0 ; (i = get_instr(ip)) ; ip++) delete i; @@ -770,21 +761,22 @@ sp_head::destroy() /* If we have non-empty LEX stack then we just came out of parser with error. Now we should delete all auxilary LEXes and restore original - THD::lex (In this case sp_head::restore_thd_mem_root() was not called - too, so m_thd points to the current thread context). - It is safe to not update LEX::ptr because further query string parsing - and execution will be stopped anyway. + THD::lex. It is safe to not update LEX::ptr because further query + string parsing and execution will be stopped anyway. */ - DBUG_ASSERT(m_lex.is_empty() || m_thd); while ((lex= (LEX *)m_lex.pop())) { - lex_end(m_thd->lex); - delete m_thd->lex; - m_thd->lex= lex; + THD *thd= lex->thd; + lex_end(thd->lex); + delete thd->lex; + thd->lex= lex; } hash_free(&m_sptabs); hash_free(&m_sroutines); + + delete m_next_cached_sp; + DBUG_VOID_RETURN; } diff --git a/sql/sp_head.h b/sql/sp_head.h index 00c96d44f70..d422adc8927 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -289,10 +289,6 @@ public: virtual ~sp_head(); - /// Free memory - void - destroy(); - bool execute_trigger(THD *thd, const LEX_STRING *db_name, diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5097ca2ad5b..a3776f59241 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2106,6 +2106,7 @@ void st_lex::cleanup_lex_after_parse_error(THD *thd) */ if (thd->lex->sphead) { + thd->lex->sphead->restore_thd_mem_root(thd); delete thd->lex->sphead; thd->lex->sphead= NULL; } |