diff options
author | unknown <monty@mysql.com> | 2004-06-25 20:13:05 +0300 |
---|---|---|
committer | unknown <monty@mysql.com> | 2004-06-25 20:13:05 +0300 |
commit | c6e23c85493688417c0274b4630a6b7c44f59d10 (patch) | |
tree | 983268d5f30394d4fa4ffdd75cd095f6227e5170 /sql/sql_handler.cc | |
parent | 4e664e3e43b1b0e2a37eadb8a6e28142db444352 (diff) | |
parent | 07589a6da51e7fb0b741cfca025202341bfa64e6 (diff) | |
download | mariadb-git-c6e23c85493688417c0274b4630a6b7c44f59d10.tar.gz |
Merge with 4.0 to get the latest bug patches to 4.1
BitKeeper/etc/ignore:
added sql/mysql_tzinfo_to_sql
BitKeeper/etc/logging_ok:
auto-union
acinclude.m4:
Auto merged
extra/perror.c:
Auto merged
include/mysql.h:
Auto merged
innobase/include/mach0data.ic:
Auto merged
innobase/include/mtr0log.h:
Auto merged
innobase/include/mtr0log.ic:
Auto merged
innobase/mem/mem0dbg.c:
Auto merged
innobase/pars/lexyy.c:
Auto merged
BitKeeper/deleted/.del-4.0.XX-gpl.ipr~f5909a9e9bd8094:
Auto merged
BitKeeper/deleted/.del-Clients and Tools.fgl~bf0f776883577f02:
Auto merged
BitKeeper/deleted/.del-Development.fgl~6392ce285e73f5fc:
Auto merged
mysql-test/mysql-test-run.sh:
Auto merged
mysql-test/r/innodb_cache.result:
Auto merged
mysql-test/r/lowercase_table2.result:
Auto merged
mysql-test/t/innodb_cache.test:
Auto merged
mysql-test/t/lowercase_table2.test:
Auto merged
sql/ha_berkeley.cc:
Auto merged
sql/handler.cc:
Auto merged
scripts/make_win_src_distribution.sh:
Auto merged
sql/sql_base.cc:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
libmysql/libmysql.c:
Merge with 4.0
mysql-test/r/bdb.result:
Merge with 4.0
mysql-test/r/range.result:
Merge with 4.0
mysql-test/t/bdb.test:
Merge with 4.0
mysys/hash.c:
Merge with 4.0
scripts/mysql_install_db.sh:
Merge with 4.0
sql/field.cc:
Merge with 4.0
sql/field.h:
Merge with 4.0
sql/mysql_priv.h:
Merge with 4.0
sql/sql_handler.cc:
Merge with 4.0
sql/sql_select.cc:
Merge with 4.0
sql/sql_table.cc:
Merge with 4.0
Diffstat (limited to 'sql/sql_handler.cc')
-rw-r--r-- | sql/sql_handler.cc | 181 |
1 files changed, 154 insertions, 27 deletions
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 7dfe707a317..c31763d7f1d 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -43,7 +43,9 @@ thd->handler_tables=tmp; } static TABLE **find_table_ptr_by_name(THD *thd,const char *db, - const char *table_name, bool is_alias); + const char *table_name, + bool is_alias, bool dont_lock, + bool *was_flushed); int mysql_ha_open(THD *thd, TABLE_LIST *tables) { @@ -66,25 +68,61 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables) return 0; } -int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok) + +/* + Close a HANDLER table. + + SYNOPSIS + mysql_ha_close() + thd Thread identifier. + tables A list of tables with the first entry to close. + dont_send_ok Suppresses the commands' ok message and + error message and error return. + dont_lock Suppresses the normal locking of LOCK_open. + + DESCRIPTION + Though this function takes a list of tables, only the first list entry + will be closed. Broadcasts a COND_refresh condition. + If mysql_ha_close() is not called from the parser, 'dont_send_ok' + must be set. + If the caller did already lock LOCK_open, it must set 'dont_lock'. + + IMPLEMENTATION + find_table_ptr_by_name() closes the table, if a FLUSH TABLE is outstanding. + It returns a NULL pointer in this case, but flags the situation in + 'was_flushed'. In that case the normal ER_UNKNOWN_TABLE error messages + is suppressed. + + RETURN + 0 ok + -1 error +*/ + +int mysql_ha_close(THD *thd, TABLE_LIST *tables, + bool dont_send_ok, bool dont_lock, bool no_alias) { - TABLE **ptr=find_table_ptr_by_name(thd, tables->db, tables->alias, 1); + TABLE **table_ptr; + bool was_flushed; - if (*ptr) + table_ptr= find_table_ptr_by_name(thd, tables->db, tables->alias, + !no_alias, dont_lock, &was_flushed); + if (*table_ptr) { (*ptr)->file->ha_index_or_rnd_end(); - VOID(pthread_mutex_lock(&LOCK_open)); - if (close_thread_table(thd, ptr)) + if (!dont_lock) + VOID(pthread_mutex_lock(&LOCK_open)); + if (close_thread_table(thd, table_ptr)) { /* Tell threads waiting for refresh that something has happened */ VOID(pthread_cond_broadcast(&COND_refresh)); } - VOID(pthread_mutex_unlock(&LOCK_open)); + if (!dont_lock) + VOID(pthread_mutex_unlock(&LOCK_open)); } - else + else if (!was_flushed && !dont_send_ok) { - my_printf_error(ER_UNKNOWN_TABLE,ER(ER_UNKNOWN_TABLE),MYF(0), - tables->alias, "HANDLER"); + my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0), + tables->alias, "HANDLER"); return -1; } if (!dont_send_ok) @@ -92,16 +130,64 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok) return 0; } -int mysql_ha_closeall(THD *thd, TABLE_LIST *tables) + +/* + Close a list of HANDLER tables. + + SYNOPSIS + mysql_ha_close_list() + thd Thread identifier. + tables The list of tables to close. If NULL, + close all HANDLER tables. + flushed Close only tables which are marked flushed. + Used only if tables is NULL. + + DESCRIPTION + The list of HANDLER tables may be NULL, in which case all HANDLER + tables are closed. Broadcasts a COND_refresh condition, for + every table closed. If 'tables' is NULL and 'flushed' is set, + all HANDLER tables marked for flush are closed. + The caller must lock LOCK_open. + + IMPLEMENTATION + find_table_ptr_by_name() closes the table, if it is marked for flush. + It returns a NULL pointer in this case, but flags the situation in + 'was_flushed'. In that case the normal ER_UNKNOWN_TABLE error messages + is suppressed. + + RETURN + 0 ok +*/ + +int mysql_ha_close_list(THD *thd, TABLE_LIST *tables, bool flushed) { - TABLE **ptr=find_table_ptr_by_name(thd, tables->db, tables->real_name, 0); - if (*ptr) + TABLE_LIST *tl_item; + TABLE **table_ptr; + + if (tables) { - (*ptr)->file->ha_index_or_rnd_end(); - if (close_thread_table(thd, ptr)) + for (tl_item= tables ; tl_item; tl_item= tl_item->next) { - /* Tell threads waiting for refresh that something has happened */ - VOID(pthread_cond_broadcast(&COND_refresh)); + mysql_ha_close(thd, tl_item, /*dont_send_ok*/ 1, + /*dont_lock*/ 1, /*no_alias*/ 1); + } + } + else + { + table_ptr= &(thd->handler_tables); + while (*table_ptr) + { + if (! flushed || ((*table_ptr)->version != refresh_version)) + { + (*table_ptr)->file->ha_index_or_rnd_end(); + if (close_thread_table(thd, table_ptr)) + { + /* Tell threads waiting for refresh that something has happened */ + VOID(pthread_cond_broadcast(&COND_refresh)); + } + continue; + } + table_ptr= &((*table_ptr)->next); } } return 0; @@ -117,7 +203,10 @@ 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, 1); + bool was_flushed; + TABLE *table= *find_table_ptr_by_name(thd, tables->db, tables->alias, + /*is_alias*/ 1, /*dont_lock*/ 0, + &was_flushed); if (!table) { my_printf_error(ER_UNKNOWN_TABLE,ER(ER_UNKNOWN_TABLE),MYF(0), @@ -298,17 +387,51 @@ err0: } +/* + Find a HANDLER table by name. + + SYNOPSIS + find_table_ptr_by_name() + thd Thread identifier. + db Database (schema) name. + table_name Table name ;-). + is_alias Table name may be an alias name. + dont_lock Suppresses the normal locking of LOCK_open. + + DESCRIPTION + Find the table 'db'.'table_name' in the list of HANDLER tables of the + thread 'thd'. If the table has been marked by FLUSH TABLE(S), close it, + flag this situation in '*was_flushed' and broadcast a COND_refresh + condition. + An empty database (schema) name matches all database (schema) names. + If the caller did already lock LOCK_open, it must set 'dont_lock'. + + IMPLEMENTATION + Just in case that the table is twice in 'thd->handler_tables' (!?!), + the loop does not break when the table was flushed. If another table + by that name was found and not flushed, '*was_flushed' is cleared again, + since a pointer to an open HANDLER table is returned. + + RETURN + *was_flushed Table has been closed due to FLUSH TABLE. + NULL A HANDLER Table by that name does not exist (any more). + != NULL Pointer to the TABLE structure. +*/ + static TABLE **find_table_ptr_by_name(THD *thd, const char *db, - const char *table_name, bool is_alias) + const char *table_name, + bool is_alias, bool dont_lock, + bool *was_flushed) { int dblen; - TABLE **ptr; + TABLE **table_ptr; DBUG_ASSERT(db); dblen= strlen(db); - ptr= &(thd->handler_tables); + table_ptr= &(thd->handler_tables); + *was_flushed= FALSE; - for (TABLE *table= *ptr; table ; table= *ptr) + for (TABLE *table= *table_ptr; table ; table= *table_ptr) { if ((db == any_db || !memcmp(table->table_cache_key, db, dblen)) && !my_strcasecmp(system_charset_info, @@ -317,18 +440,22 @@ static TABLE **find_table_ptr_by_name(THD *thd, const char *db, { if (table->version != refresh_version) { - VOID(pthread_mutex_lock(&LOCK_open)); - if (close_thread_table(thd, ptr)) + if (!dont_lock) + VOID(pthread_mutex_lock(&LOCK_open)); + if (close_thread_table(thd, table_ptr)) { /* Tell threads waiting for refresh that something has happened */ VOID(pthread_cond_broadcast(&COND_refresh)); } - VOID(pthread_mutex_unlock(&LOCK_open)); + if (!dont_lock) + VOID(pthread_mutex_unlock(&LOCK_open)); + *was_flushed= TRUE; continue; } + *was_flushed= FALSE; break; } - ptr= &(table->next); + table_ptr= &(table->next); } - return ptr; + return table_ptr; } |