summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/lock.cc21
-rw-r--r--sql/sql_base.cc41
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/table.cc20
-rw-r--r--sql/table.h65
5 files changed, 95 insertions, 54 deletions
diff --git a/sql/lock.cc b/sql/lock.cc
index 8e75ea42f7d..06f538a2a03 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -874,6 +874,8 @@ end:
int lock_table_name(THD *thd, TABLE_LIST *table_list, bool check_in_use)
{
TABLE *table;
+ TABLE_SHARE *share;
+ char *key_buff;
char key[MAX_DBKEY_LENGTH];
char *db= table_list->db;
uint key_length;
@@ -903,17 +905,18 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list, bool check_in_use)
}
/*
Create a table entry with the right key and with an old refresh version
- Note that we must use my_malloc() here as this is freed by the table
- cache
+ Note that we must use my_multi_malloc() here as this is freed by the
+ table cache
*/
- if (!(table= (TABLE*) my_malloc(sizeof(*table)+ sizeof(TABLE_SHARE)+
- key_length, MYF(MY_WME | MY_ZEROFILL))))
+ if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+ &table, sizeof(*table),
+ &share, sizeof(*share),
+ &key_buff, key_length,
+ NULL))
DBUG_RETURN(-1);
- table->s= (TABLE_SHARE*) (table+1);
- memcpy((table->s->table_cache_key.str= (char*) (table->s+1)), key,
- key_length);
- table->s->table_cache_key.length= key_length;
- table->s->tmp_table= INTERNAL_TMP_TABLE; // for intern_close_table
+ table->s= share;
+ share->set_table_cache_key(key_buff, key, key_length);
+ share->tmp_table= INTERNAL_TMP_TABLE; // for intern_close_table
table->in_use= thd;
table->locked_by_name=1;
table_list->table=table;
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 1c733e3c12d..32a622c7401 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -634,6 +634,7 @@ TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name)
static void close_handle_and_leave_table_as_lock(TABLE *table)
{
TABLE_SHARE *share, *old_share= table->s;
+ char *key_buff;
MEM_ROOT *mem_root= &table->mem_root;
DBUG_ENTER("close_handle_and_leave_table_as_lock");
@@ -642,20 +643,14 @@ static void close_handle_and_leave_table_as_lock(TABLE *table)
This has to be done to ensure that the table share is removed from
the table defintion cache as soon as the last instance is removed
*/
- if ((share= (TABLE_SHARE*) alloc_root(mem_root, sizeof(*share))))
+ if (multi_alloc_root(mem_root,
+ &share, sizeof(*share),
+ &key_buff, old_share->table_cache_key.length,
+ NULL))
{
bzero((char*) share, sizeof(*share));
- share->db.str= memdup_root(mem_root, old_share->db.str,
- old_share->db.length+1);
- share->db.length= old_share->db.length;
- share->table_name.str= memdup_root(mem_root,
- old_share->table_name.str,
- old_share->table_name.length+1);
- share->table_name.length= old_share->table_name.length;
- share->table_cache_key.str= memdup_root(mem_root,
- old_share->table_cache_key.str,
- old_share->table_cache_key.length);
- share->table_cache_key.length= old_share->table_cache_key.length;
+ share->set_table_cache_key(key_buff, old_share->table_cache_key.str,
+ old_share->table_cache_key.length);
share->tmp_table= INTERNAL_TMP_TABLE; // for intern_close_table()
}
@@ -1603,28 +1598,18 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *db,
const char *table_name)
{
char *key;
+ uint key_length;
TABLE_SHARE *share= table->s;
TABLE_LIST table_list;
- uint db_length, table_length;
DBUG_ENTER("rename_temporary_table");
- if (!(key=(char*) alloc_root(&share->mem_root,
- (uint) (db_length= strlen(db))+
- (uint) (table_length= strlen(table_name))+6+4)))
+ if (!(key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH)))
DBUG_RETURN(1); /* purecov: inspected */
table_list.db= (char*) db;
table_list.table_name= (char*) table_name;
- share->db.str= share->table_cache_key.str= key;
- share->db.length= db_length;
- share->table_cache_key.length= create_table_def_key(thd, key,
- &table_list, 1);
- /*
- Here we use the fact that table_name is stored as the second component
- in the 'key' (after db_name), where components are separated with \0
- */
- share->table_name.str= key+db_length+1;
- share->table_name.length= table_length;
+ key_length= create_table_def_key(thd, key, &table_list, 1);
+ share->set_table_cache_key(key, key_length);
DBUG_RETURN(0);
}
@@ -1749,10 +1734,7 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
{
TABLE *table= table_list->table;
TABLE_SHARE *share;
- char *db= table_list->db;
char *table_name= table_list->table_name;
- char key[MAX_DBKEY_LENGTH];
- uint key_length;
TABLE orig_table;
DBUG_ENTER("reopen_name_locked_table");
@@ -1762,7 +1744,6 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
DBUG_RETURN(TRUE);
orig_table= *table;
- key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
if (open_unireg_entry(thd, table, table_list, table_name,
table->s->table_cache_key.str,
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 7eda55c6a3f..a882f0b066d 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -8645,8 +8645,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
share->primary_key= MAX_KEY; // Indicate no primary key
share->keys_for_keyread.init();
share->keys_in_use.init();
- /* For easier error reporting */
- share->table_cache_key= share->db;
/* Calculate which type of fields we will store in the temporary table */
diff --git a/sql/table.cc b/sql/table.cc
index f0a864287b0..179cfb2be14 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -93,6 +93,7 @@ TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
{
MEM_ROOT mem_root;
TABLE_SHARE *share;
+ char *key_buff, *path_buff;
char path[FN_REFLEN];
uint path_length;
DBUG_ENTER("alloc_table_share");
@@ -103,22 +104,17 @@ TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
table_list->db,
table_list->table_name, "", 0);
init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
- if ((share= (TABLE_SHARE*) alloc_root(&mem_root,
- sizeof(*share) + key_length +
- path_length +1)))
+ if (multi_alloc_root(&mem_root,
+ &share, sizeof(*share),
+ &key_buff, key_length,
+ &path_buff, path_length + 1,
+ NULL))
{
bzero((char*) share, sizeof(*share));
- share->table_cache_key.str= (char*) (share+1);
- share->table_cache_key.length= key_length;
- memcpy(share->table_cache_key.str, key, key_length);
- /* Use the fact the key is db/0/table_name/0 */
- share->db.str= share->table_cache_key.str;
- share->db.length= strlen(share->db.str);
- share->table_name.str= share->db.str + share->db.length + 1;
- share->table_name.length= strlen(share->table_name.str);
+ share->set_table_cache_key(key_buff, key, key_length);
- share->path.str= share->table_cache_key.str+ key_length;
+ share->path.str= path_buff;
share->path.length= path_length;
strmov(share->path.str, path);
share->normalized_path.str= share->path.str;
diff --git a/sql/table.h b/sql/table.h
index 7675c27823b..c13a23468ae 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -138,7 +138,16 @@ typedef struct st_table_share
CHARSET_INFO *table_charset; /* Default charset of string fields */
MY_BITMAP all_set;
- /* A pair "database_name\0table_name\0", widely used as simply a db name */
+ /*
+ Key which is used for looking-up table in table cache and in the list
+ of thread's temporary tables. Has the form of:
+ "database_name\0table_name\0" + optional part for temporary tables.
+
+ Note that all three 'table_cache_key', 'db' and 'table_name' members
+ must be set (and be non-zero) for tables in table cache. They also
+ should correspond to each other.
+ To ensure this one can use set_table_cache() methods.
+ */
LEX_STRING table_cache_key;
LEX_STRING db; /* Pointer to db */
LEX_STRING table_name; /* Table name (for open) */
@@ -223,6 +232,60 @@ typedef struct st_table_share
uint part_state_len;
handlerton *default_part_db_type;
#endif
+
+
+ /*
+ Set share's table cache key and update its db and table name appropriately.
+
+ SYNOPSIS
+ set_table_cache_key()
+ key_buff Buffer with already built table cache key to be
+ referenced from share.
+ key_length Key length.
+
+ NOTES
+ Since 'key_buff' buffer will be referenced from share it should has same
+ life-time as share itself.
+ This method automatically ensures that TABLE_SHARE::table_name/db have
+ appropriate values by using table cache key as their source.
+ */
+
+ void set_table_cache_key(char *key_buff, uint key_length)
+ {
+ table_cache_key.str= key_buff;
+ table_cache_key.length= key_length;
+ /*
+ Let us use the fact that the key is "db/0/table_name/0" + optional
+ part for temporary tables.
+ */
+ db.str= table_cache_key.str;
+ db.length= strlen(db.str);
+ table_name.str= db.str + db.length + 1;
+ table_name.length= strlen(table_name.str);
+ }
+
+
+ /*
+ Set share's table cache key and update its db and table name appropriately.
+
+ SYNOPSIS
+ set_table_cache_key()
+ key_buff Buffer to be used as storage for table cache key
+ (should be at least key_length bytes).
+ key Value for table cache key.
+ key_length Key length.
+
+ NOTE
+ Since 'key_buff' buffer will be used as storage for table cache key
+ it should has same life-time as share itself.
+ */
+
+ void set_table_cache_key(char *key_buff, const char *key, uint key_length)
+ {
+ memcpy(key_buff, key, key_length);
+ set_table_cache_key(key_buff, key_length);
+ }
+
} TABLE_SHARE;