From 23549493aad7f078dc86adc912c1b0b2b06c8568 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 5 Apr 2006 14:39:20 +0200 Subject: [PATCH] BUG#5390 - problems with merge tables Additional fix for INSERT DELAYED with subselect. Originally detected in 5.1, but 5.0 could also be affected. The user thread creates a dummy table object, which is not included in the lock. The 'real' table is opened and locked by the 'delayed' system thread. The dummy object is now marked as not locked and this is tested in mysql_lock_have_duplicate(). sql/lock.cc: BUG#5390 - problems with merge tables Additional fix for INSERT DELAYED with subselect. The user thread creates a dummy table object, which is not included in the lock. Changed to safer asserts. sql/sql_insert.cc: BUG#5390 - problems with merge tables Marked the dummy table object as not being included in the lock. --- sql/lock.cc | 13 +++++++++---- sql/sql_insert.cc | 5 ++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sql/lock.cc b/sql/lock.cc index 01cdca0b6ee..a584b063a0b 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -530,8 +530,11 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle, THR_LOCK_DATA **end_data2; DBUG_ENTER("mysql_lock_have_duplicate"); - /* Table may not be defined for derived or view tables. */ - if (! (table= needle->table)) + /* + Table may not be defined for derived or view tables. + Table may not be part of a lock for delayed operations. + */ + if (! (table= needle->table) || ! table->lock_count) goto end; /* A temporary table does not have locks. */ @@ -550,7 +553,8 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle, lock_tables= mylock->table; /* Prepare table related variables that don't change in loop. */ - DBUG_ASSERT(table == lock_tables[table->lock_position]); + DBUG_ASSERT((table->lock_position < mylock->table_count) && + (table == lock_tables[table->lock_position])); table_lock_data= lock_locks + table->lock_data_start; end_data= table_lock_data + table->lock_count; @@ -563,7 +567,8 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle, continue; /* All tables in list must be in lock. */ - DBUG_ASSERT(table2 == lock_tables[table2->lock_position]); + DBUG_ASSERT((table2->lock_position < mylock->table_count) && + (table2 == lock_tables[table2->lock_position])); for (lock_data2= lock_locks + table2->lock_data_start, end_data2= lock_data2 + table2->lock_count; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index ad9606acb83..67aab57b880 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1536,7 +1536,10 @@ TABLE *delayed_insert::get_local_table(THD* client_thd) /* Adjust in_use for pointing to client thread */ copy->in_use= client_thd; - + + /* Adjust lock_count. This table object is not part of a lock. */ + copy->lock_count= 0; + return copy; /* Got fatal error */