diff options
author | unknown <monty@narttu.mysql.fi> | 2003-06-01 12:32:53 +0300 |
---|---|---|
committer | unknown <monty@narttu.mysql.fi> | 2003-06-01 12:32:53 +0300 |
commit | 2ef52d46a4f5b0c34bee26b0f70d672b6ee9325e (patch) | |
tree | 5524062586f42802c3aab500a005cf3dc593b2a1 | |
parent | dbdcae8bef9092979a84ff490bb2eb791b5366fc (diff) | |
download | mariadb-git-2ef52d46a4f5b0c34bee26b0f70d672b6ee9325e.tar.gz |
Fixed bug in ALTER TABLE DISABLE KEYS and INSERT DELAYED. Bug #478
mysql-test/r/alter_table.result:
new results
mysql-test/r/lowercase_table.result:
new results
mysql-test/t/alter_table.test:
Test of ALTER TABLE DISABLE KEYS + INSERT DELAYED
mysql-test/t/lowercase_table.test:
Added test of alias name comparison
sql/mysql_priv.h:
Made closed_cached_table local
sql/sql_table.cc:
Fixed bug in ALTER TABLE DISABLE KEYS and INSERT DELAYED
-rw-r--r-- | mysql-test/r/alter_table.result | 5 | ||||
-rw-r--r-- | mysql-test/r/lowercase_table.result | 12 | ||||
-rw-r--r-- | mysql-test/t/alter_table.test | 9 | ||||
-rw-r--r-- | mysql-test/t/lowercase_table.test | 11 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/sql_table.cc | 133 |
6 files changed, 118 insertions, 53 deletions
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index cfbc46bc78f..e2d9cc30ad9 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -276,3 +276,8 @@ t1 0 a 1 a A 3 NULL NULL YES BTREE t1 0 a 2 b A 300 NULL NULL YES BTREE t1 1 b 1 b A 100 NULL NULL YES BTREE drop table t1; +CREATE TABLE t1 (i int(10), index(i) ); +ALTER TABLE t1 DISABLE KEYS; +INSERT DELAYED INTO t1 VALUES(1),(2),(3); +ALTER TABLE t1 ENABLE KEYS; +drop table t1; diff --git a/mysql-test/r/lowercase_table.result b/mysql-test/r/lowercase_table.result index 1caaf317c96..d32228216b8 100644 --- a/mysql-test/r/lowercase_table.result +++ b/mysql-test/r/lowercase_table.result @@ -13,3 +13,15 @@ show tables like 't_'; Tables_in_test (t_) t3 drop table t3; +create table t1 (a int); +select count(*) from T1; +count(*) +0 +select count(*) from t1; +count(*) +0 +select count(T1.a) from t1; +Unknown table 'T1' in field list +select count(bags.a) from t1 as Bags; +Unknown table 'bags' in field list +drop table t1; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 96f969c8776..a3ab62afc69 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -133,3 +133,12 @@ analyze table t1; show keys from t1; drop table t1; +# +# Test of ALTER TABLE DELAYED +# + +CREATE TABLE t1 (i int(10), index(i) ); +ALTER TABLE t1 DISABLE KEYS; +INSERT DELAYED INTO t1 VALUES(1),(2),(3); +ALTER TABLE t1 ENABLE KEYS; +drop table t1; diff --git a/mysql-test/t/lowercase_table.test b/mysql-test/t/lowercase_table.test index 0d04e6c7df7..b3453dfd3c4 100644 --- a/mysql-test/t/lowercase_table.test +++ b/mysql-test/t/lowercase_table.test @@ -12,3 +12,14 @@ ALTER TABLE T2 RENAME T3; show tables like 't_'; drop table t3; +# +# Test alias +# +create table t1 (a int); +select count(*) from T1; +select count(*) from t1; +--error 1109 +select count(T1.a) from t1; +--error 1109 +select count(bags.a) from t1 as Bags; +drop table t1; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 614cb8cadf6..41a39f0d24c 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -422,7 +422,6 @@ bool mysql_rename_table(enum db_type base, const char * old_name, const char *new_db, const char * new_name); -bool close_cached_table(THD *thd,TABLE *table); int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys); int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop_list); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 07ec1d67538..f3620b860a7 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -912,58 +912,76 @@ mysql_rename_table(enum db_type base, } /* - close table in this thread and force close + reopen in other threads - This assumes that the calling thread has lock on LOCK_open - Win32 clients must also have a WRITE LOCK on the table ! + Force all other threads to stop using the table + + SYNOPSIS + wait_while_table_is_used() + thd Thread handler + table Table to remove from cache + + NOTES + When returning, the table will be unusable for other threads until + the table is closed. + + PREREQUISITES + Lock on LOCK_open + Win32 clients must also have a WRITE LOCK on the table ! */ -static void safe_remove_from_cache(THD *thd,TABLE *table) +static void wait_while_table_is_used(THD *thd,TABLE *table) { - DBUG_ENTER("safe_remove_from_cache"); - if (table) - { - DBUG_PRINT("enter",("table: %s", table->real_name)); - VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Close all data files - /* Mark all tables that are in use as 'old' */ - mysql_lock_abort(thd,table); // end threads waiting on lock + DBUG_PRINT("enter",("table: %s", table->real_name)); + DBUG_ENTER("wait_while_table_is_used"); + safe_mutex_assert_owner(&LOCK_open); -#if defined(USING_TRANSACTIONS) || defined( __WIN__) || defined( __EMX__) || !defined(OS2) - /* Wait until all there are no other threads that has this table open */ - while (remove_table_from_cache(thd,table->table_cache_key, - table->real_name)) - { - dropping_tables++; - (void) pthread_cond_wait(&COND_refresh,&LOCK_open); - dropping_tables--; - } -#else - (void) remove_table_from_cache(thd,table->table_cache_key, - table->real_name); -#endif - /* When lock on LOCK_open is freed other threads can continue */ - pthread_cond_broadcast(&COND_refresh); + VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Close all data files + /* Mark all tables that are in use as 'old' */ + mysql_lock_abort(thd, table); // end threads waiting on lock + + /* Wait until all there are no other threads that has this table open */ + while (remove_table_from_cache(thd,table->table_cache_key, + table->real_name)) + { + dropping_tables++; + (void) pthread_cond_wait(&COND_refresh,&LOCK_open); + dropping_tables--; } DBUG_VOID_RETURN; } +/* + Close a cached table + + SYNOPSIS + clsoe_cached_table() + thd Thread handler + table Table to remove from cache -bool close_cached_table(THD *thd,TABLE *table) + NOTES + Function ends by signaling threads waiting for the table to try to + reopen the table. + + PREREQUISITES + Lock on LOCK_open + Win32 clients must also have a WRITE LOCK on the table ! +*/ + +static bool close_cached_table(THD *thd, TABLE *table) { DBUG_ENTER("close_cached_table"); - safe_mutex_assert_owner(&LOCK_open); - - if (table) + + wait_while_table_is_used(thd,table); + /* Close lock if this is not got with LOCK TABLES */ + if (thd->lock) { - safe_remove_from_cache(thd,table); - /* Close lock if this is not got with LOCK TABLES */ - if (thd->lock) - { - mysql_unlock_tables(thd, thd->lock); - thd->lock=0; // Start locked threads - } - /* Close all copies of 'table'. This also frees all LOCK TABLES lock */ - thd->open_tables=unlink_open_table(thd,thd->open_tables,table); + mysql_unlock_tables(thd, thd->lock); + thd->lock=0; // Start locked threads } + /* Close all copies of 'table'. This also frees all LOCK TABLES lock */ + thd->open_tables=unlink_open_table(thd,thd->open_tables,table); + + /* When lock on LOCK_open is freed other threads can continue */ + pthread_cond_broadcast(&COND_refresh); DBUG_RETURN(0); } @@ -1094,10 +1112,13 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id); - pthread_mutex_lock(&LOCK_open); - close_cached_table(thd,table_list->table); - pthread_mutex_unlock(&LOCK_open); - + /* If we could open the table, close it */ + if (table_list->table) + { + pthread_mutex_lock(&LOCK_open); + close_cached_table(thd, table); + pthread_mutex_unlock(&LOCK_open); + } if (lock_and_wait_for_table_name(thd,table_list)) { error= -1; @@ -1494,11 +1515,10 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, else { *fn_ext(new_name)=0; - close_cached_table(thd,table); + close_cached_table(thd, table); if (mysql_rename_table(old_db_type,db,table_name,new_db,new_name)) error= -1; } - VOID(pthread_cond_broadcast(&COND_refresh)); VOID(pthread_mutex_unlock(&LOCK_open)); } if (!error) @@ -1507,12 +1527,18 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, case LEAVE_AS_IS: break; case ENABLE: - safe_remove_from_cache(thd,table); - error= table->file->activate_all_index(thd); + VOID(pthread_mutex_lock(&LOCK_open)); + wait_while_table_is_used(thd, table); + VOID(pthread_mutex_unlock(&LOCK_open)); + error= table->file->activate_all_index(thd); + /* COND_refresh will be signaled in close_thread_tables() */ break; case DISABLE: - safe_remove_from_cache(thd,table); + VOID(pthread_mutex_lock(&LOCK_open)); + wait_while_table_is_used(thd, table); + VOID(pthread_mutex_unlock(&LOCK_open)); table->file->deactivate_non_unique_index(HA_POS_ERROR); + /* COND_refresh will be signaled in close_thread_tables() */ break; } } @@ -1936,7 +1962,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, close the original table at before doing the rename */ table_name=thd->strdup(table_name); // must be saved - if (close_cached_table(thd,table)) + if (close_cached_table(thd, table)) { // Aborted VOID(quick_rm_table(new_db_type,new_db,tmp_name)); VOID(pthread_mutex_unlock(&LOCK_open)); @@ -1970,7 +1996,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, This shouldn't happen. We solve this the safe way by closing the locked table. */ - close_cached_table(thd,table); + if (table) + close_cached_table(thd,table); VOID(pthread_mutex_unlock(&LOCK_open)); goto err; } @@ -1980,7 +2007,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, Not table locking or alter table with rename free locks and remove old table */ - close_cached_table(thd,table); + if (table) + close_cached_table(thd,table); VOID(quick_rm_table(old_db_type,db,old_name)); } else @@ -2000,7 +2028,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (close_data_tables(thd,db,table_name) || reopen_tables(thd,1,0)) { // This shouldn't happen - close_cached_table(thd,table); // Remove lock for table + if (table) + close_cached_table(thd,table); // Remove lock for table VOID(pthread_mutex_unlock(&LOCK_open)); goto err; } |