diff options
Diffstat (limited to '')
-rw-r--r-- | sql/transaction.cc | 70 |
1 files changed, 47 insertions, 23 deletions
diff --git a/sql/transaction.cc b/sql/transaction.cc index f34307ac..1ae0928e 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -181,7 +181,7 @@ bool trans_begin(THD *thd, uint flags) } thd->tx_read_only= false; /* - This flags that tx_read_only was set explicitly, rather than + This flags that transaction_read_only was set explicitly, rather than just from the session's default. */ #ifndef EMBEDDED_LIBRARY @@ -583,17 +583,17 @@ bool trans_rollback_stmt(THD *thd) DBUG_RETURN(FALSE); } -/* Find a named savepoint in the current transaction. */ -static SAVEPOINT ** -find_savepoint(THD *thd, LEX_CSTRING name) +/** Find a savepoint by name in a savepoint list */ +SAVEPOINT** find_savepoint_in_list(THD *thd, LEX_CSTRING name, + SAVEPOINT ** const list) { - SAVEPOINT **sv= &thd->transaction->savepoints; + SAVEPOINT **sv= list; while (*sv) { if (system_charset_info->strnncoll( - (uchar *) name.str, name.length, - (uchar *) (*sv)->name, (*sv)->length) == 0) + (uchar *) name.str, name.length, + (uchar *) (*sv)->name, (*sv)->length) == 0) break; sv= &(*sv)->prev; } @@ -601,6 +601,43 @@ find_savepoint(THD *thd, LEX_CSTRING name) return sv; } +/* Find a named savepoint in the current transaction. */ +static SAVEPOINT ** +find_savepoint(THD *thd, LEX_CSTRING name) +{ + return find_savepoint_in_list(thd, name, &thd->transaction->savepoints); +} + +SAVEPOINT* savepoint_add(THD *thd, LEX_CSTRING name, SAVEPOINT **list, + int (*release_old)(THD*, SAVEPOINT*)) +{ + DBUG_ENTER("savepoint_add"); + + SAVEPOINT **sv= find_savepoint_in_list(thd, name, list); + + SAVEPOINT *newsv; + + if (*sv) /* old savepoint of the same name exists */ + { + newsv= *sv; + if (release_old){ + int error= release_old(thd, *sv); + if (error) + DBUG_RETURN(NULL); + } + *sv= (*sv)->prev; + } + else if ((newsv= (SAVEPOINT *) alloc_root(&thd->transaction->mem_root, + savepoint_alloc_size)) == NULL) + { + my_error(ER_OUT_OF_RESOURCES, MYF(0)); + DBUG_RETURN(NULL); + } + + newsv->name= strmake_root(&thd->transaction->mem_root, name.str, name.length); + newsv->length= (uint)name.length; + DBUG_RETURN(newsv); +} /** Set a named transaction savepoint. @@ -614,7 +651,6 @@ find_savepoint(THD *thd, LEX_CSTRING name) bool trans_savepoint(THD *thd, LEX_CSTRING name) { - SAVEPOINT **sv, *newsv; DBUG_ENTER("trans_savepoint"); if (!(thd->in_multi_stmt_transaction_mode() || thd->in_sub_stmt) || @@ -624,23 +660,11 @@ bool trans_savepoint(THD *thd, LEX_CSTRING name) if (thd->transaction->xid_state.check_has_uncommitted_xa()) DBUG_RETURN(TRUE); - sv= find_savepoint(thd, name); + SAVEPOINT *newsv= savepoint_add(thd, name, &thd->transaction->savepoints, + ha_release_savepoint); - if (*sv) /* old savepoint of the same name exists */ - { - newsv= *sv; - ha_release_savepoint(thd, *sv); - *sv= (*sv)->prev; - } - else if ((newsv= (SAVEPOINT *) alloc_root(&thd->transaction->mem_root, - savepoint_alloc_size)) == NULL) - { - my_error(ER_OUT_OF_RESOURCES, MYF(0)); + if (newsv == NULL) DBUG_RETURN(TRUE); - } - - newsv->name= strmake_root(&thd->transaction->mem_root, name.str, name.length); - newsv->length= (uint)name.length; /* if we'll get an error here, don't add new savepoint to the list. |