diff options
author | serg@serg.mysql.com <> | 2003-01-28 14:36:22 +0100 |
---|---|---|
committer | serg@serg.mysql.com <> | 2003-01-28 14:36:22 +0100 |
commit | 4fb3244014418bd76e8cf755275798a166d980d7 (patch) | |
tree | 440af93c0ae6daf3a1db266aa402a888dc276e30 | |
parent | 52e440b9a784289bb1d502e9891c7250bf9b0b47 (diff) | |
download | mariadb-git-4fb3244014418bd76e8cf755275798a166d980d7.tar.gz |
fixed "DROP table_open_in_handler" hang
-rw-r--r-- | mysql-test/r/handler.result | 8 | ||||
-rw-r--r-- | mysql-test/t/handler.test | 21 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/sql_handler.cc | 37 | ||||
-rw-r--r-- | sql/sql_table.cc | 3 |
5 files changed, 49 insertions, 21 deletions
diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result index 35765c48049..9760719ecf2 100644 --- a/mysql-test/r/handler.result +++ b/mysql-test/r/handler.result @@ -136,4 +136,10 @@ a b handler t2 read last; You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 handler t2 close; -drop table if exists t1; +handler t1 open as t2; +drop table t1; +create table t1 (a int); +insert into t1 values (17); +handler t2 read first; +Unknown table 't2' in HANDLER +drop table t1; diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test index 4f1b11c80ff..f5bab7cf337 100644 --- a/mysql-test/t/handler.test +++ b/mysql-test/t/handler.test @@ -28,13 +28,15 @@ handler t2 read a next; handler t2 read a=(15); handler t2 read a=(16); -!$1070 handler t2 read a=(19,"fff"); +--error 1070 +handler t2 read a=(19,"fff"); handler t2 read b=(19,"fff"); handler t2 read b=(19,"yyy"); handler t2 read b=(19); -!$1109 handler t1 read a last; +--error 1109 +handler t1 read a last; handler t2 read a=(11); handler t2 read a>=(11); @@ -60,8 +62,19 @@ handler t2 read first; handler t2 read next; alter table t1 type=MyISAM; handler t2 read next; -!$1064 handler t2 read last; +--error 1064 +handler t2 read last; handler t2 close; -drop table if exists t1; + +# +# DROP TABLE +# +handler t1 open as t2; +drop table t1; +create table t1 (a int); +insert into t1 values (17); +--error 1109 +handler t2 read first; +drop table t1; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 5a957514d28..f858251db94 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -501,6 +501,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, /* sql_handler.cc */ int mysql_ha_open(THD *thd, TABLE_LIST *tables); int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok=0); +int mysql_ha_closeall(THD *thd, TABLE_LIST *tables, bool dont_send_ok=0); int mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows); diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 66dcf37d07f..eeaa574c69d 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -43,8 +43,8 @@ thd->open_tables=thd->handler_tables; \ thd->handler_tables=tmp; } -static TABLE **find_table_ptr_by_name(THD *thd, const char *db, - const char *table_name); +static TABLE **find_table_ptr_by_name(THD *thd,const char *db, + const char *table_name, bool is_alias); int mysql_ha_open(THD *thd, TABLE_LIST *tables) { @@ -68,7 +68,7 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables) int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok) { - TABLE **ptr=find_table_ptr_by_name(thd, tables->db, tables->alias); + TABLE **ptr=find_table_ptr_by_name(thd, tables->db, tables->alias, 1); if (*ptr) { @@ -87,6 +87,21 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok) return 0; } +int mysql_ha_closeall(THD *thd, TABLE_LIST *tables, bool dont_send_ok) +{ + TABLE **ptr=find_table_ptr_by_name(thd, tables->db, tables->real_name, 0); + + DBUG_ASSERT(dont_send_ok); + if (*ptr) + { +// if (!dont_send_ok) VOID(pthread_mutex_lock(&LOCK_open)); + close_thread_table(thd, ptr); +// if (!dont_send_ok) VOID(pthread_mutex_unlock(&LOCK_open)); + } +// if (!dont_send_ok) send_ok(&thd->net); + return 0; +} + static enum enum_ha_read_modes rkey_to_rnext[]= { RNEXT, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV }; @@ -97,7 +112,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, ha_rows select_limit,ha_rows offset_limit) { int err, keyno=-1; - TABLE *table=*find_table_ptr_by_name(thd, tables->db, tables->alias); + TABLE *table=*find_table_ptr_by_name(thd, tables->db, tables->alias, 1); if (!table) { my_printf_error(ER_UNKNOWN_TABLE,ER(ER_UNKNOWN_TABLE),MYF(0), @@ -250,17 +265,8 @@ err0: return -1; } -/************************************************************************** - 2Monty: It could easily happen, that the following service functions are - already defined somewhere in the code, but I failed to find them. - If this is the case, just say a word and I'll use old functions here. -**************************************************************************/ - -/* Note: this function differs from find_locked_table() because we're looking - here for alias, not real table name - */ static TABLE **find_table_ptr_by_name(THD *thd, const char *db, - const char *alias) + const char *table_name, bool is_alias) { int dblen; TABLE **ptr; @@ -273,9 +279,10 @@ static TABLE **find_table_ptr_by_name(THD *thd, const char *db, for (TABLE *table=*ptr; table ; table=*ptr) { if (!memcmp(table->table_cache_key, db, dblen) && - !my_strcasecmp(table->table_name,alias)) + !my_strcasecmp((is_alias ? table->table_name : table->real_name),table_name)) break; ptr=&(table->next); } return ptr; } + diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a763d6b6b91..a9edfc1ec1f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -74,7 +74,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists) } error=mysql_rm_table_part2(thd,tables,if_exists,0); - err: + err: pthread_mutex_unlock(&LOCK_open); VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh @@ -136,6 +136,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, for (table=tables ; table ; table=table->next) { char *db=table->db ? table->db : thd->db; + mysql_ha_closeall(thd, table, 1); if (!close_temporary_table(thd, db, table->real_name)) { tmp_table_deleted=1; |