diff options
Diffstat (limited to 'sql/lock.cc')
-rw-r--r-- | sql/lock.cc | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/sql/lock.cc b/sql/lock.cc index 3367c6a2900..0db23f54c50 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -695,6 +695,9 @@ static void print_lock_error(int error) case HA_ERR_READ_ONLY_TRANSACTION: textno=ER_READ_ONLY_TRANSACTION; break; + case HA_ERR_LOCK_DEADLOCK: + textno=ER_LOCK_DEADLOCK; + break; default: textno=ER_CANT_LOCK; break; @@ -870,3 +873,62 @@ bool make_global_read_lock_block_commit(THD *thd) thd->exit_cond(old_message); DBUG_RETURN(error); } + +/* + Take transactional table lock for all tables in the list + + SYNOPSIS + transactional_lock_tables + thd Thread THD + tables list of tables + counter number of tables in the list + + NOTES + + RETURN + 0 - OK + -1 - error + +*/ +int transactional_lock_tables(THD *thd, TABLE_LIST *tables, uint counter) +{ + uint i; + int lock_type,error=0; + TABLE_LIST *table; + TABLE **start,**ptr; + + DBUG_ENTER("transactional_lock_tables"); + + if (!(ptr=start=(TABLE**) sql_alloc(sizeof(TABLE*) * counter))) + return -1; + + for (table= tables; table; table= table->next_global) + { + if (!table->placeholder() && !table->schema_table) + *(ptr++)= table->table; + } + + for (i=1 ; i <= counter ; i++, start++) + { + DBUG_ASSERT((*start)->reginfo.lock_type >= TL_READ); + lock_type=F_WRLCK; /* Lock exclusive */ + + if ((*start)->db_stat & HA_READ_ONLY || + ((*start)->reginfo.lock_type >= TL_READ && + (*start)->reginfo.lock_type <= TL_READ_NO_INSERT)) + lock_type=F_RDLCK; + + if ((error=(*start)->file->transactional_table_lock(thd, lock_type))) + { + print_lock_error(error); + DBUG_RETURN(-1); + } + else + { + (*start)->db_stat &= ~ HA_BLOCK_LOCK; + (*start)->current_lock= lock_type; + } + } + + DBUG_RETURN(0); +} |