summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <serg@serg.mysql.com>2001-04-15 22:56:20 +0200
committerunknown <serg@serg.mysql.com>2001-04-15 22:56:20 +0200
commit09f0384e7abce9d9cb744d0a20b897b5a77ef747 (patch)
tree3e165fc973e16ec4067bc0b0de1f997e599e621d /sql
parentc778d3374cdaa5760ce41d9febe070266055a6f0 (diff)
downloadmariadb-git-09f0384e7abce9d9cb744d0a20b897b5a77ef747.tar.gz
fully functional HANDLER table CLOSE
sql/mysql_priv.h: new function: close_thread_table() sql/sql_base.cc: new function: close_thread_table()
Diffstat (limited to 'sql')
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/sql_base.cc79
-rw-r--r--sql/sql_handler.cc25
3 files changed, 60 insertions, 45 deletions
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 31293951a90..2c4ad21de95 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -430,6 +430,7 @@ bool send_fields(THD *thd,List<Item> &item,uint send_field_count);
void free_io_cache(TABLE *entry);
void intern_close_table(TABLE *entry);
void close_thread_tables(THD *thd,bool locked=0);
+bool close_thread_table(THD *thd, TABLE **table_ptr);
void close_temporary_tables(THD *thd);
TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name);
bool close_temporary_table(THD *thd, const char *db, const char *table_name);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 8980684dc66..a0bb003eeb4 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -421,40 +421,9 @@ void close_thread_tables(THD *thd, bool locked)
DBUG_PRINT("info", ("thd->open_tables=%p", thd->open_tables));
- for (table=thd->open_tables ; table ; table=next)
- {
- next=table->next;
- if (table->version != refresh_version ||
- thd->version != refresh_version || !table->db_stat)
- {
- VOID(hash_delete(&open_cache,(byte*) table));
- found_old_table=1;
- }
- else
- {
- if (table->flush_version != flush_version)
- {
- table->flush_version=flush_version;
- table->file->extra(HA_EXTRA_FLUSH);
- }
- else
- {
- // Free memory and reset for next loop
- table->file->extra(HA_EXTRA_RESET);
- }
- table->in_use=0;
- if (unused_tables)
- {
- table->next=unused_tables; /* Link in last */
- table->prev=unused_tables->prev;
- unused_tables->prev=table;
- table->prev->next=table;
- }
- else
- unused_tables=table->next=table->prev=table;
- }
- }
- thd->open_tables=0;
+ while (thd->open_tables)
+ found_old_table|=close_thread_table(thd, &thd->open_tables);
+
/* Free tables to hold down open files */
while (open_cache.records > table_cache_size && unused_tables)
VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */
@@ -470,6 +439,48 @@ void close_thread_tables(THD *thd, bool locked)
DBUG_VOID_RETURN;
}
+/* move one table to free list */
+
+bool close_thread_table(THD *thd, TABLE **table_ptr)
+{
+ DBUG_ENTER("close_thread_table");
+
+ bool found_old_table=0;
+ TABLE *table=*table_ptr;
+
+ *table_ptr=table->next;
+ if (table->version != refresh_version ||
+ thd->version != refresh_version || !table->db_stat)
+ {
+ VOID(hash_delete(&open_cache,(byte*) table));
+ found_old_table=1;
+ }
+ else
+ {
+ if (table->flush_version != flush_version)
+ {
+ table->flush_version=flush_version;
+ table->file->extra(HA_EXTRA_FLUSH);
+ }
+ else
+ {
+ // Free memory and reset for next loop
+ table->file->extra(HA_EXTRA_RESET);
+ }
+ table->in_use=0;
+ if (unused_tables)
+ {
+ table->next=unused_tables; /* Link in last */
+ table->prev=unused_tables->prev;
+ unused_tables->prev=table;
+ table->prev->next=table;
+ }
+ else
+ unused_tables=table->next=table->prev=table;
+ }
+ DBUG_RETURN(found_old_table);
+}
+
/* Close and delete temporary tables */
void close_temporary(TABLE *table,bool delete_table)
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 9dbfc6f8626..d0ac2387a1c 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -43,7 +43,7 @@
thd->open_tables=thd->handler_tables; \
thd->handler_tables=tmp; }
-static TABLE *find_table_by_name(THD *thd, char *db, char *table_name);
+static TABLE **find_table_ptr_by_name(THD *thd, char *db, char *table_name);
int mysql_ha_open(THD *thd, TABLE_LIST *tables)
{
@@ -59,11 +59,11 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables)
int mysql_ha_close(THD *thd, TABLE_LIST *tables)
{
- /* Perhaps, we should close table here.
- But it's not easy - *tables is a single-linked list, designed
- to be closed at all once.
- So, why bother ? All the tables will be closed at thread exit.
- */
+ TABLE **ptr=find_table_ptr_by_name(thd, tables->db, tables->name);
+
+ if (*ptr)
+ close_thread_table(thd, ptr);
+
send_ok(&thd->net);
return 0;
}
@@ -77,7 +77,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_by_name(thd, tables->db, tables->name);
+ TABLE *table=*find_table_ptr_by_name(thd, tables->db, tables->name);
if (!table)
{
my_printf_error(ER_UNKNOWN_TABLE,ER(ER_UNKNOWN_TABLE),MYF(0),
@@ -231,19 +231,22 @@ err:
/* Note: this function differs from find_locked_table() because we're looking
here for alias, not real table name
*/
-static TABLE *find_table_by_name(THD *thd, char *db, char *table_name)
+static TABLE **find_table_ptr_by_name(THD *thd, char *db, char *table_name)
{
int dblen;
+ TABLE **ptr;
if (!db || ! *db) db=thd->db;
if (!db || ! *db) db="";
dblen=strlen(db);
+ ptr=&(thd->handler_tables);
- for (TABLE *table=thd->handler_tables; table ; table=table->next)
+ for (TABLE *table=*ptr; table ; table=*ptr)
{
if (!memcmp(table->table_cache_key, db, dblen) &&
!my_strcasecmp(table->table_name,table_name))
- return table;
+ break;
+ ptr=&(table->next);
}
- return(0);
+ return ptr;
}