1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-24 11:21:21 +03:00

Fix for bug #13825 "Triggers: crash if release savepoint" and for general

handling of savepoints in stored routines.

Fixed ha_rollback_to_savepoint()/ha_savepoint()/ha_release_savepoint()
functions to properly handle savepoints inside of stored functions and
triggers.
Also now when we invoke stored function or trigger we create new savepoint
level. We destroy it at the end of function/trigger execution and return back
to old savepoint level.


mysql-test/r/sp_trans.result:
  Added test for bug #13825 "Triggers: crash if release savepoint" and for
  general handling of savepoints in stored routines.
mysql-test/t/sp_trans.test:
  Added test for bug #13825 "Triggers: crash if release savepoint" and for
  general handling of savepoints in stored routines.
sql/ha_innodb.cc:
  innobase_savepoint():
    Replaced check which always failed due to similar check in caller
    with assertion.
sql/handler.cc:
  ha_rollback_to_savepoint()/ha_savepoint()/ha_release_savepoint():
    Changed functions to properly support handling of savepoints
    inside of stored functions and triggers.
sql/sql_class.cc:
  THD::reset_sub_statement_state()/restore_sub_statement_state():
    When we invoke stored function or trigger we should create new savepoint
    level. We should destroy it at the end of function/trigger execution and
    return back to old savepoint level. To support this behavior we should
    save and reset list of current savepoints on entering function and restore
    old list when we leave it.
sql/sql_class.h:
  Sub_statement_state:
    When we invoke stored function or trigger we should create new savepoint
    level. We should destroy it at the end of function/trigger execution and
    return back to old savepoint level. To support this behavior added "savepoint"
    member which is used to save/restore list of current savepoints on
    entering/leaving function.
sql/sql_parse.cc:
  mysql_execute_command():
    Changed processing of SQLCOM_SAVEPOINT so now it is not ignored when
    we are in autocommit mode and savepoint is set inside of stored
    function or trigger.
This commit is contained in:
unknown
2005-11-19 15:09:23 +03:00
parent ac8b32f9c0
commit 11d4d7e6ff
7 changed files with 411 additions and 14 deletions

View File

@@ -1145,10 +1145,10 @@ int ha_update_statistics()
int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
{
int error=0;
THD_TRANS *trans=&thd->transaction.all;
THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
&thd->transaction.all);
handlerton **ht=trans->ht, **end_ht;
DBUG_ENTER("ha_rollback_to_savepoint");
DBUG_ASSERT(thd->transaction.stmt.ht[0] == 0);
trans->nht=sv->nht;
trans->no_2pc=0;
@@ -1176,7 +1176,7 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
for (; *ht ; ht++)
{
int err;
if ((err= (*(*ht)->rollback)(thd, 1)))
if ((err= (*(*ht)->rollback)(thd, !thd->in_sub_stmt)))
{ // cannot happen
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
error=1;
@@ -1196,10 +1196,10 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
int ha_savepoint(THD *thd, SAVEPOINT *sv)
{
int error=0;
THD_TRANS *trans=&thd->transaction.all;
THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
&thd->transaction.all);
handlerton **ht=trans->ht;
DBUG_ENTER("ha_savepoint");
DBUG_ASSERT(thd->transaction.stmt.ht[0] == 0);
#ifdef USING_TRANSACTIONS
for (; *ht; ht++)
{
@@ -1225,9 +1225,10 @@ int ha_savepoint(THD *thd, SAVEPOINT *sv)
int ha_release_savepoint(THD *thd, SAVEPOINT *sv)
{
int error=0;
handlerton **ht=thd->transaction.all.ht, **end_ht;
THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
&thd->transaction.all);
handlerton **ht=trans->ht, **end_ht;
DBUG_ENTER("ha_release_savepoint");
DBUG_ASSERT(thd->transaction.stmt.ht[0] == 0);
end_ht=ht+sv->nht;
for (; ht < end_ht; ht++)