1
0
mirror of https://github.com/MariaDB/server.git synced 2026-01-06 05:22:24 +03:00

Auto merge

This commit is contained in:
He Zhenxing
2009-04-08 16:17:26 +08:00
46 changed files with 956 additions and 234 deletions

View File

@@ -1587,27 +1587,11 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
{ // Using table locks
TABLE *best_table= 0;
int best_distance= INT_MIN;
bool check_if_used= thd->prelocked_mode &&
((int) table_list->lock_type >=
(int) TL_WRITE_ALLOW_WRITE);
for (table=thd->open_tables; table ; table=table->next)
{
if (table->s->key_length == key_length &&
!memcmp(table->s->table_cache_key, key, key_length))
{
if (check_if_used && table->query_id &&
table->query_id != thd->query_id)
{
/*
If we are in stored function or trigger we should ensure that
we won't change table that is already used by calling statement.
So if we are opening table for writing, we should check that it
is not already open by some calling stamement.
*/
my_error(ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG, MYF(0),
table->s->table_name);
DBUG_RETURN(0);
}
if (!my_strcasecmp(system_charset_info, table->alias, alias) &&
table->query_id != thd->query_id && /* skip tables already used */
!(thd->prelocked_mode && table->query_id))
@@ -1631,13 +1615,13 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
{
best_distance= distance;
best_table= table;
if (best_distance == 0 && !check_if_used)
if (best_distance == 0)
{
/*
If we have found perfect match and we don't need to check that
table is not used by one of calling statements (assuming that
we are inside of function or trigger) we can finish iterating
through open tables list.
We have found a perfect match and can finish iterating
through open tables list. Check for table use conflict
between calling statement and SP/trigger is done in
lock_tables().
*/
break;
}
@@ -2936,9 +2920,9 @@ static bool check_lock_and_start_stmt(THD *thd, TABLE *table,
lock_type Lock to use for open
NOTE
This function don't do anything like SP/SF/views/triggers analysis done
in open_tables(). It is intended for opening of only one concrete table.
And used only in special contexts.
This function doesn't do anything like SP/SF/views/triggers analysis done
in open_tables()/lock_tables(). It is intended for opening of only one
concrete table. And used only in special contexts.
RETURN VALUES
table Opened table
@@ -3254,8 +3238,36 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
TABLE_LIST *first_not_own= thd->lex->first_not_own_table();
for (table= tables; table != first_not_own; table= table->next_global)
{
if (!table->placeholder() &&
check_lock_and_start_stmt(thd, table->table, table->lock_type))
if (table->placeholder())
continue;
/*
In a stored function or trigger we should ensure that we won't change
a table that is already used by the calling statement.
*/
if (thd->prelocked_mode &&
table->lock_type >= TL_WRITE_ALLOW_WRITE)
{
for (TABLE* opentab= thd->open_tables; opentab; opentab= opentab->next)
{
/*
issue an error if the tables are the same (by key comparison),
but query_id isn't
*/
if (opentab->query_id &&
table->table->query_id != opentab->query_id &&
table->table->s->key_length == opentab->s->key_length &&
!memcmp(table->table->s->table_cache_key,
opentab->s->table_cache_key, opentab->s->key_length))
{
my_error(ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG, MYF(0),
table->table->s->table_name);
DBUG_RETURN(-1);
}
}
}
if (check_lock_and_start_stmt(thd, table->table, table->lock_type))
{
ha_rollback_stmt(thd);
DBUG_RETURN(-1);