summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authordlenev@brandersnatch.localdomain <>2005-07-01 13:01:46 +0400
committerdlenev@brandersnatch.localdomain <>2005-07-01 13:01:46 +0400
commit56ff9f16535d2cb94f6a983b40ed6b6f16e5b370 (patch)
treef780b41399823750ea4737fc932dfa4c34d0319c /sql/sp_head.cc
parentf2e358d9dbde3eaf5b62d047b720c078eebbeb41 (diff)
downloadmariadb-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.cc26
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);
}