diff options
author | Ignacio Galarza <iggy@mysql.com> | 2009-03-17 16:29:24 -0400 |
---|---|---|
committer | Ignacio Galarza <iggy@mysql.com> | 2009-03-17 16:29:24 -0400 |
commit | 0d588edf61c93ab67fb7e26101a0fc00d021bb11 (patch) | |
tree | 3c313f70fd16653491985d8e8108fb5b99f0d5d0 /storage/myisammrg | |
parent | 5b7347bda31b9d66cd78937e5dc339f553b9a736 (diff) | |
parent | 7ca1ebd83a1a7d291593be7a94f5a37298dfc863 (diff) | |
download | mariadb-git-0d588edf61c93ab67fb7e26101a0fc00d021bb11.tar.gz |
auto-merge
Diffstat (limited to 'storage/myisammrg')
-rw-r--r-- | storage/myisammrg/ha_myisammrg.cc | 89 | ||||
-rw-r--r-- | storage/myisammrg/ha_myisammrg.h | 2 | ||||
-rw-r--r-- | storage/myisammrg/myrg_open.c | 5 |
3 files changed, 89 insertions, 7 deletions
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index dc04699f42b..061af97d0fb 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -116,7 +116,7 @@ static handler *myisammrg_create_handler(handlerton *hton, */ ha_myisammrg::ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg) - :handler(hton, table_arg), file(0) + :handler(hton, table_arg), file(0), is_cloned(0) {} @@ -413,7 +413,28 @@ int ha_myisammrg::open(const char *name, int mode __attribute__((unused)), /* retrieve children table list. */ my_errno= 0; - if (!(file= myrg_parent_open(name, myisammrg_parent_open_callback, this))) + if (is_cloned) + { + /* + Open and attaches the MyISAM tables,that are under the MERGE table + parent, on the MyISAM storage engine interface directly within the + MERGE engine. The new MyISAM table instances, as well as the MERGE + clone itself, are not visible in the table cache. This is not a + problem because all locking is handled by the original MERGE table + from which this is cloned of. + */ + if (!(file= myrg_open(table->s->normalized_path.str, table->db_stat, + HA_OPEN_IGNORE_IF_LOCKED))) + { + DBUG_PRINT("error", ("my_errno %d", my_errno)); + DBUG_RETURN(my_errno ? my_errno : -1); + } + + file->children_attached= TRUE; + + info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); + } + else if (!(file= myrg_parent_open(name, myisammrg_parent_open_callback, this))) { DBUG_PRINT("error", ("my_errno %d", my_errno)); DBUG_RETURN(my_errno ? my_errno : -1); @@ -422,6 +443,55 @@ int ha_myisammrg::open(const char *name, int mode __attribute__((unused)), DBUG_RETURN(0); } +/** + Returns a cloned instance of the current handler. + + @return A cloned handler instance. + */ +handler *ha_myisammrg::clone(MEM_ROOT *mem_root) +{ + MYRG_TABLE *u_table,*newu_table; + ha_myisammrg *new_handler= + (ha_myisammrg*) get_new_handler(table->s, mem_root, table->s->db_type()); + if (!new_handler) + return NULL; + + /* Inform ha_myisammrg::open() that it is a cloned handler */ + new_handler->is_cloned= TRUE; + /* + Allocate handler->ref here because otherwise ha_open will allocate it + on this->table->mem_root and we will not be able to reclaim that memory + when the clone handler object is destroyed. + */ + if (!(new_handler->ref= (uchar*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2))) + { + delete new_handler; + return NULL; + } + + if (new_handler->ha_open(table, table->s->normalized_path.str, table->db_stat, + HA_OPEN_IGNORE_IF_LOCKED)) + { + delete new_handler; + return NULL; + } + + /* + Iterate through the original child tables and + copy the state into the cloned child tables. + We need to do this because all the child tables + can be involved in delete. + */ + newu_table= new_handler->file->open_tables; + for (u_table= file->open_tables; u_table < file->end_table; u_table++) + { + newu_table->table->state= u_table->table->state; + newu_table++; + } + + return new_handler; + } + /** @brief Attach children to a MERGE table. @@ -613,9 +683,10 @@ int ha_myisammrg::close(void) DBUG_ENTER("ha_myisammrg::close"); /* Children must not be attached here. Unless the MERGE table has no - children. In this case children_attached is always true. + children or the handler instance has been cloned. In these cases + children_attached is always true. */ - DBUG_ASSERT(!this->file->children_attached || !this->file->tables); + DBUG_ASSERT(!this->file->children_attached || !this->file->tables || this->is_cloned); rc= myrg_close(file); file= 0; DBUG_RETURN(rc); @@ -801,6 +872,16 @@ int ha_myisammrg::info(uint flag) table->s->crashed= 1; #endif stats.data_file_length= mrg_info.data_file_length; + if (mrg_info.errkey >= (int) table_share->keys) + { + /* + If value of errkey is higher than the number of keys + on the table set errkey to MAX_KEY. This will be + treated as unknown key case and error message generator + won't try to locate key causing segmentation fault. + */ + mrg_info.errkey= MAX_KEY; + } errkey= mrg_info.errkey; table->s->keys_in_use.set_prefix(table->s->keys); stats.mean_rec_length= mrg_info.reclength; diff --git a/storage/myisammrg/ha_myisammrg.h b/storage/myisammrg/ha_myisammrg.h index 4e7ddebb836..21d41c9d75a 100644 --- a/storage/myisammrg/ha_myisammrg.h +++ b/storage/myisammrg/ha_myisammrg.h @@ -25,6 +25,7 @@ class ha_myisammrg: public handler { MYRG_INFO *file; + my_bool is_cloned; /* This instance has been cloned */ public: TABLE_LIST *next_child_attach; /* next child to attach */ @@ -60,6 +61,7 @@ class ha_myisammrg: public handler int open(const char *name, int mode, uint test_if_locked); int attach_children(void); int detach_children(void); + virtual handler *clone(MEM_ROOT *mem_root); int close(void); int write_row(uchar * buf); int update_row(const uchar * old_data, uchar * new_data); diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c index 64b4be2b7ca..14ba2853b22 100644 --- a/storage/myisammrg/myrg_open.c +++ b/storage/myisammrg/myrg_open.c @@ -33,7 +33,6 @@ myrg_attach_children(). Please duplicate changes in these functions or make common sub-functions. */ -/* purecov: begin deadcode */ /* not used in MySQL server */ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) { @@ -198,7 +197,6 @@ err: my_errno=save_errno; DBUG_RETURN (NULL); } -/* purecov: end */ /** @@ -428,10 +426,11 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking, if (!m_info->rec_per_key_part) { if(!(m_info->rec_per_key_part= (ulong*) - my_malloc(key_parts * sizeof(long), MYF(MY_WME|MY_ZEROFILL)))) + my_malloc(key_parts * sizeof(long), MYF(MY_WME)))) goto err; /* purecov: inspected */ errpos= 1; } + bzero((char*) m_info->rec_per_key_part, key_parts * sizeof(long)); } /* Add MyISAM table info. */ |