diff options
author | Mikael Ronstrom <mikael@mysql.com> | 2009-06-11 12:07:59 +0200 |
---|---|---|
committer | Mikael Ronstrom <mikael@mysql.com> | 2009-06-11 12:07:59 +0200 |
commit | 506c7fd47dd28e5726852e47d117bfbb37677005 (patch) | |
tree | 796cc97d1d103e18e0672d9b57dee4c54857073c /storage/myisammrg | |
parent | 4557f4ee9e9975966be6fa7c4fa553b30992ca6d (diff) | |
parent | fbb96b339ae5fcce19446fd27a2fb75e49b960f8 (diff) | |
download | mariadb-git-506c7fd47dd28e5726852e47d117bfbb37677005.tar.gz |
Merge MySQL 5.1.35 into MySQL 5.4
Diffstat (limited to 'storage/myisammrg')
-rw-r--r-- | storage/myisammrg/ha_myisammrg.cc | 102 | ||||
-rw-r--r-- | storage/myisammrg/ha_myisammrg.h | 2 | ||||
-rw-r--r-- | storage/myisammrg/myrg_open.c | 5 |
3 files changed, 96 insertions, 13 deletions
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 999dcf00b93..492bc15f749 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -117,7 +117,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) {} @@ -138,7 +138,8 @@ extern int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, extern int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo, uint t1_keys, uint t1_recs, MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo, - uint t2_keys, uint t2_recs, bool strict); + uint t2_keys, uint t2_recs, bool strict, + TABLE *table_arg); static void split_file_name(const char *file_name, LEX_STRING *db, LEX_STRING *name); @@ -219,7 +220,7 @@ static int myisammrg_parent_open_callback(void *callback_param, TABLE_LIST *child_l; const char *db; const char *table_name; - uint dirlen; + size_t dirlen; char dir_path[FN_REFLEN]; DBUG_ENTER("myisammrg_parent_open_callback"); @@ -414,7 +415,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); @@ -423,6 +445,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. @@ -526,7 +597,7 @@ int ha_myisammrg::attach_children(void) if (check_definition(keyinfo, recinfo, keys, recs, u_table->table->s->keyinfo, u_table->table->s->rec, u_table->table->s->base.keys, - u_table->table->s->base.fields, false)) + u_table->table->s->base.fields, false, NULL)) { DBUG_PRINT("error", ("table definition mismatch: '%s'", u_table->table->filename)); @@ -614,9 +685,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); @@ -824,6 +896,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; @@ -984,7 +1066,7 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd, static void split_file_name(const char *file_name, LEX_STRING *db, LEX_STRING *name) { - uint dir_length, prefix_length; + size_t dir_length, prefix_length; char buff[FN_REFLEN]; db->length= 0; @@ -1057,7 +1139,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form, const char **table_names, **pos; TABLE_LIST *tables= (TABLE_LIST*) create_info->merge_list.first; THD *thd= current_thd; - uint dirlgt= dirname_length(name); + size_t dirlgt= dirname_length(name); DBUG_ENTER("ha_myisammrg::create"); /* Allocate a table_names array in thread mem_root. */ @@ -1116,7 +1198,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form, void ha_myisammrg::append_create_info(String *packet) { const char *current_db; - uint db_length; + size_t db_length; THD *thd= current_thd; MYRG_TABLE *open_table, *first; 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. */ |