diff options
author | dlenev@brandersnatch.localdomain <> | 2005-07-01 13:01:46 +0400 |
---|---|---|
committer | dlenev@brandersnatch.localdomain <> | 2005-07-01 13:01:46 +0400 |
commit | 56ff9f16535d2cb94f6a983b40ed6b6f16e5b370 (patch) | |
tree | f780b41399823750ea4737fc932dfa4c34d0319c /sql/sp_head.cc | |
parent | f2e358d9dbde3eaf5b62d047b720c078eebbeb41 (diff) | |
download | mariadb-git-56ff9f16535d2cb94f6a983b40ed6b6f16e5b370.tar.gz |
"Fix" for bug #11394 "Recursion in SP crash server" and bug #11600
"Stored procedures: crash with function calling itself".
Disallow recursive stored routines until we either make Item's and LEX
reentrant safe or will use spearate sp_head instances (and thus separate
LEX objects and Item trees) for each routine invocation.
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r-- | sql/sp_head.cc | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc index e4dc64c993d..3d5525015c6 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -312,7 +312,8 @@ sp_head::operator delete(void *ptr, size_t size) sp_head::sp_head() :Query_arena(&main_mem_root, INITIALIZED_FOR_SP), m_returns_cs(NULL), m_has_return(FALSE), - m_simple_case(FALSE), m_multi_results(FALSE), m_in_handler(FALSE) + m_simple_case(FALSE), m_multi_results(FALSE), m_in_handler(FALSE), + m_is_invoked(FALSE) { extern byte * sp_table_key(const byte *ptr, uint *plen, my_bool first); @@ -587,6 +588,28 @@ sp_head::execute(THD *thd) DBUG_RETURN(-1); } + if (m_is_invoked) + { + /* + We have to disable recursion for stored routines since in + many cases LEX structure and many Item's can't be used in + reentrant way now. + + TODO: We can circumvent this problem by using separate + sp_head instances for each recursive invocation. + + NOTE: Theoretically arguments of procedure can be evaluated + before its invocation so there should be no problem with + recursion. But since we perform cleanup for CALL statement + as for any other statement only after its execution, its LEX + structure is not reusable for recursive calls. Thus we have + to prohibit recursion for stored procedures too. + */ + my_error(ER_SP_NO_RECURSION, MYF(0)); + DBUG_RETURN(-1); + } + m_is_invoked= TRUE; + dbchanged= FALSE; if (m_db.length && (ret= sp_use_new_db(thd, m_db.str, olddb, sizeof(olddb), 0, &dbchanged))) @@ -704,6 +727,7 @@ sp_head::execute(THD *thd) if (! thd->killed) ret= sp_change_db(thd, olddb, 0); } + m_is_invoked= FALSE; DBUG_RETURN(ret); } |