null+****@clear*****
null+****@clear*****
2011年 11月 26日 (土) 15:39:01 JST
Kentoku 2011-11-26 06:39:01 +0000 (Sat, 26 Nov 2011) New Revision: e85fcebe868c101bfad188b01f457e7482dc575b Log: Alter table support. refs #1168 Modified files: ha_mroonga.cc ha_mroonga.h mrn_table.cc mrn_table.h Modified: ha_mroonga.cc (+86 -51) =================================================================== --- ha_mroonga.cc 2011-11-25 13:26:52 +0000 (bae05b0) +++ ha_mroonga.cc 2011-11-26 06:39:01 +0000 (2d73f62) @@ -83,7 +83,7 @@ const char *grn_obj_get_value_(grn_ctx *ctx, grn_obj *obj, grn_id id, uint32 *si /* global variables */ static pthread_mutex_t mrn_db_mutex; static pthread_mutex_t mrn_log_mutex; -static handlerton *mrn_hton_ptr; +handlerton *mrn_hton_ptr; HASH mrn_open_tables; pthread_mutex_t mrn_open_tables_mutex; @@ -137,8 +137,8 @@ static grn_logger_info mrn_logger_info = { }; /* global hashes and mutexes */ -static HASH mrn_allocated_thds; -static pthread_mutex_t mrn_allocated_thds_mutex; +HASH mrn_allocated_thds; +pthread_mutex_t mrn_allocated_thds_mutex; static uchar *mrn_allocated_thds_get_key(THD *thd, size_t *length, my_bool not_used __attribute__ ((unused))) @@ -336,7 +336,7 @@ my_bool last_insert_grn_id_init(UDF_INIT *initid, UDF_ARGS *args, char *message) int last_insert_grn_id(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { THD *thd = current_thd; - st_mrn_slot_data *slot_data = (st_mrn_slot_data*) *thd_ha_data(thd, mrn_hton_ptr); + st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, FALSE); if (slot_data == NULL) { return 0; } @@ -1014,7 +1014,8 @@ static int mrn_deinit(void *p) pthread_mutex_lock(&mrn_allocated_thds_mutex); while ((tmp_thd = (THD *) my_hash_element(&mrn_allocated_thds, 0))) { - void *slot_ptr = *thd_ha_data(tmp_thd, mrn_hton_ptr); + mrn_clear_alter_share(tmp_thd); + void *slot_ptr = mrn_get_slot_data(tmp_thd, FALSE); if (slot_ptr) free(slot_ptr); *thd_ha_data(tmp_thd, mrn_hton_ptr) = (void *) NULL; my_hash_delete(&mrn_allocated_thds, (uchar *) tmp_thd); @@ -1487,6 +1488,7 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table, base_key_info = NULL; DBUG_RETURN(HA_ERR_OUT_OF_MEM); } + hnd->init(); error = hnd->ha_create(name, table, info); MRN_SET_BASE_SHARE_KEY(tmp_share, table->s); MRN_SET_BASE_TABLE_KEY(this, table); @@ -2178,14 +2180,6 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info) int i, error = 0; MRN_SHARE *tmp_share; MRN_DBUG_ENTER_METHOD(); - uint sql_command = thd_sql_command(ha_thd()); - if ( - sql_command == SQLCOM_CREATE_INDEX || - sql_command == SQLCOM_DROP_INDEX || - sql_command == SQLCOM_ALTER_TABLE - ) - DBUG_RETURN(HA_ERR_WRONG_COMMAND); - /* checking data type of virtual columns */ if (!(tmp_share = mrn_get_share(name, table, &error))) @@ -2245,6 +2239,7 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked) base_key_info = NULL; DBUG_RETURN(HA_ERR_OUT_OF_MEM); } + wrap_handler->init(); error = wrap_handler->ha_open(table, name, mode, test_if_locked); } else { #ifdef MRN_HANDLER_CLONE_NEED_NAME @@ -2699,6 +2694,7 @@ int ha_mroonga::wrapper_delete_table(const char *name, MRN_SHARE *tmp_share, MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share); DBUG_RETURN(HA_ERR_OUT_OF_MEM); } + hnd->init(); MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share); if ((error = hnd->ha_delete_table(name))) @@ -2781,53 +2777,71 @@ int ha_mroonga::storage_delete_table(const char *name, MRN_SHARE *tmp_share, int ha_mroonga::delete_table(const char *name) { int error = 0; + THD *thd = ha_thd(); char db_name[MRN_MAX_PATH_SIZE]; char tbl_name[MRN_MAX_PATH_SIZE]; char decode_name[MRN_MAX_PATH_SIZE]; TABLE_LIST table_list; - TABLE_SHARE *tmp_table_share; + TABLE_SHARE *tmp_table_share = NULL; TABLE tmp_table; MRN_SHARE *tmp_share; + st_mrn_alter_share *alter_share, *tmp_alter_share; MRN_DBUG_ENTER_METHOD(); - uint sql_command = thd_sql_command(ha_thd()); - if ( - sql_command == SQLCOM_CREATE_INDEX || - sql_command == SQLCOM_DROP_INDEX || - sql_command == SQLCOM_ALTER_TABLE - ) - DBUG_RETURN(HA_ERR_WRONG_COMMAND); mrn_decode((uchar *) decode_name, (uchar *) decode_name + MRN_MAX_PATH_SIZE, (const uchar *) name, (const uchar *) name + strlen(name)); mrn_db_name_gen(decode_name, db_name); mrn_table_name_gen(decode_name, tbl_name); + st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, FALSE); + if (slot_data && slot_data->first_alter_share) + { + tmp_alter_share = NULL; + alter_share = slot_data->first_alter_share; + while (alter_share) + { + if (!strcmp(alter_share->path, name)) + { + /* found */ + tmp_table_share = alter_share->alter_share; + if (tmp_alter_share) + tmp_alter_share->next = alter_share->next; + else + slot_data->first_alter_share = alter_share->next; + free(alter_share); + break; + } + tmp_alter_share = alter_share; + alter_share = alter_share->next; + } + } + if (!tmp_table_share) + { #if MYSQL_VERSION_ID >= 50500 - table_list.init_one_table(db_name, strlen(db_name), - tbl_name, strlen(tbl_name), tbl_name, TL_WRITE); + table_list.init_one_table(db_name, strlen(db_name), + tbl_name, strlen(tbl_name), tbl_name, TL_WRITE); #else - table_list.init_one_table(db_name, tbl_name, TL_WRITE); + table_list.init_one_table(db_name, tbl_name, TL_WRITE); #endif #if MYSQL_VERSION_ID >= 50500 - mysql_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); #endif - if (!(tmp_table_share = mrn_get_table_share(&table_list, &error))) - { + if (!(tmp_table_share = mrn_q_get_table_share(&table_list, name, &error))) + { #if MYSQL_VERSION_ID >= 50500 - mysql_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); #endif - DBUG_RETURN(error); - } + DBUG_RETURN(error); + } #if MYSQL_VERSION_ID >= 50500 - mysql_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); #endif - /* This is previous version */ - tmp_table_share->version--; + } tmp_table.s = tmp_table_share; #ifdef WITH_PARTITION_STORAGE_ENGINE tmp_table.part_info = NULL; #endif if (!(tmp_share = mrn_get_share(name, &tmp_table, &error))) { - mrn_free_table_share(tmp_table_share); + mrn_q_free_table_share(tmp_table_share); DBUG_RETURN(error); } @@ -2842,7 +2856,7 @@ int ha_mroonga::delete_table(const char *name) #if MYSQL_VERSION_ID >= 50500 mysql_mutex_lock(&LOCK_open); #endif - mrn_free_table_share(tmp_table_share); + mrn_q_free_table_share(tmp_table_share); #if MYSQL_VERSION_ID >= 50500 mysql_mutex_unlock(&LOCK_open); #endif @@ -3541,21 +3555,14 @@ int ha_mroonga::storage_write_row(uchar *buf) } // for UDF last_insert_grn_id() - st_mrn_slot_data *slot_data = (st_mrn_slot_data*) *thd_ha_data(thd, mrn_hton_ptr); + st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, TRUE); if (slot_data == NULL) { - slot_data = (st_mrn_slot_data*) malloc(sizeof(st_mrn_slot_data)); - *thd_ha_data(thd, mrn_hton_ptr) = (void *) slot_data; - pthread_mutex_lock(&mrn_allocated_thds_mutex); - if (my_hash_insert(&mrn_allocated_thds, (uchar*) thd)) - { #ifndef DBUG_OFF dbug_tmp_restore_column_map(table->read_set, tmp_map); #endif DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - pthread_mutex_unlock(&mrn_allocated_thds_mutex); } - slot_data->last_insert_record_id = record_id; + slot_data->last_insert_record_id = (int) record_id; #ifndef DBUG_OFF dbug_tmp_restore_column_map(table->read_set, tmp_map); @@ -6297,6 +6304,7 @@ int ha_mroonga::storage_reset() int ha_mroonga::reset() { int error = 0; + THD *thd = ha_thd(); MRN_DBUG_ENTER_METHOD(); DBUG_PRINT("info", ("mroonga: this=%p", this)); clear_search_result(); @@ -6308,6 +6316,7 @@ int ha_mroonga::reset() ignoring_no_key_columns = false; ignoring_duplicated_key = false; fulltext_searching = false; + mrn_clear_alter_share(thd); DBUG_RETURN(error); } @@ -7152,6 +7161,7 @@ int ha_mroonga::wrapper_rename_table(const char *from, const char *to, MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share); DBUG_RETURN(HA_ERR_OUT_OF_MEM); } + hnd->init(); MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share); if ((error = hnd->ha_rename_table(from, to))) @@ -7275,6 +7285,7 @@ int ha_mroonga::storage_rename_table(const char *from, const char *to, int ha_mroonga::rename_table(const char *from, const char *to) { int error = 0; + THD *thd = ha_thd(); char from_db_name[MRN_MAX_PATH_SIZE]; char to_db_name[MRN_MAX_PATH_SIZE]; char from_tbl_name[MRN_MAX_PATH_SIZE]; @@ -7306,7 +7317,7 @@ int ha_mroonga::rename_table(const char *from, const char *to) #if MYSQL_VERSION_ID >= 50500 mysql_mutex_lock(&LOCK_open); #endif - if (!(tmp_table_share = mrn_get_table_share(&table_list, &error))) + if (!(tmp_table_share = mrn_q_get_table_share(&table_list, from, &error))) { #if MYSQL_VERSION_ID >= 50500 mysql_mutex_unlock(&LOCK_open); @@ -7316,18 +7327,39 @@ int ha_mroonga::rename_table(const char *from, const char *to) #if MYSQL_VERSION_ID >= 50500 mysql_mutex_unlock(&LOCK_open); #endif - /* This is previous version */ - tmp_table_share->version--; tmp_table.s = tmp_table_share; #ifdef WITH_PARTITION_STORAGE_ENGINE tmp_table.part_info = NULL; #endif if (!(tmp_share = mrn_get_share(from, &tmp_table, &error))) { - mrn_free_table_share(tmp_table_share); + mrn_q_free_table_share(tmp_table_share); DBUG_RETURN(error); } + if (to_tbl_name[0] == '#') + { + st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, TRUE); + if (!slot_data) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + st_mrn_alter_share *alter_share = + (st_mrn_alter_share *) malloc(sizeof(st_mrn_alter_share)); + if (!alter_share) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + alter_share->next = NULL; + strcpy(alter_share->path, to); + alter_share->alter_share = tmp_table_share; + if (slot_data->first_alter_share) + { + st_mrn_alter_share *tmp_alter_share = slot_data->first_alter_share; + while (tmp_alter_share->next) + tmp_alter_share = tmp_alter_share->next; + tmp_alter_share->next = alter_share; + } else { + slot_data->first_alter_share = alter_share; + } + } + if (tmp_share->wrapper_mode) { error = wrapper_rename_table(from, to, tmp_share, @@ -7338,13 +7370,16 @@ int ha_mroonga::rename_table(const char *from, const char *to) } mrn_free_share(tmp_share); + if (to_tbl_name[0] != '#') + { #if MYSQL_VERSION_ID >= 50500 - mysql_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); #endif - mrn_free_table_share(tmp_table_share); + mrn_q_free_table_share(tmp_table_share); #if MYSQL_VERSION_ID >= 50500 - mysql_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); #endif + } DBUG_RETURN(error); } Modified: ha_mroonga.h (+0 -5) =================================================================== --- ha_mroonga.h 2011-11-25 13:26:52 +0000 (415a0e0) +++ ha_mroonga.h 2011-11-26 06:39:01 +0000 (a6ad1d6) @@ -113,11 +113,6 @@ struct st_mrn_ft_info ha_mroonga *mroonga; }; -struct st_mrn_slot_data -{ - grn_id last_insert_record_id; -}; - /* handler class */ class ha_mroonga: public handler { Modified: mrn_table.cc (+86 -0) =================================================================== --- mrn_table.cc 2011-11-25 13:26:52 +0000 (9241622) +++ mrn_table.cc 2011-11-26 06:39:01 +0000 (47b2517) @@ -42,6 +42,9 @@ extern HASH mrn_open_tables; extern pthread_mutex_t mrn_open_tables_mutex; extern char *mrn_default_parser; +extern handlerton *mrn_hton_ptr; +extern HASH mrn_allocated_thds; +extern pthread_mutex_t mrn_allocated_thds_mutex; char *mrn_create_string(const char *str, uint length) { @@ -755,6 +758,48 @@ void mrn_free_table_share(TABLE_SHARE *share) DBUG_VOID_RETURN; } +TABLE_SHARE *mrn_q_get_table_share(TABLE_LIST *table_list, const char *path, + int *error) +{ + uint key_length; + TABLE_SHARE *share; + THD *thd = current_thd; + DBUG_ENTER("mrn_q_get_table_share"); +#if MYSQL_VERSION_ID >= 50603 + const char *key; + key_length = get_table_def_key(table_list, &key); +#else + char key[MAX_DBKEY_LENGTH]; + key_length = create_table_def_key(thd, key, table_list, FALSE); +#endif +#if MYSQL_VERSION_ID >= 50500 + if (!(share = alloc_table_share(table_list, key, key_length))) + { + *error = ER_CANT_OPEN_FILE; + DBUG_RETURN(NULL); + } + share->path.str = (char *) path; + share->path.length = strlen(path); + share->normalized_path.str = share->path.str; + share->normalized_path.length = share->path.length; + if (open_table_def(thd, share, 0)) + { + *error = ER_CANT_OPEN_FILE; + DBUG_RETURN(NULL); + } +#else + share = get_table_share(thd, table_list, key, key_length, 0, error); +#endif + DBUG_RETURN(share); +} + +void mrn_q_free_table_share(TABLE_SHARE *share) +{ + DBUG_ENTER("mrn_q_free_table_share"); + share->destroy(); + DBUG_VOID_RETURN; +} + KEY *mrn_create_key_info_for_table(MRN_SHARE *share, TABLE *table, int *error) { uint *wrap_key_nr = share->wrap_key_nr, i, j; @@ -825,3 +870,44 @@ uint mrn_decode(uchar *buf_st, uchar *buf_ed, const uchar *st, const uchar *ed) DBUG_PRINT("info", ("mroonga: out=%s", buf_st)); DBUG_RETURN(buf - buf_st); } + +st_mrn_slot_data *mrn_get_slot_data(THD *thd, bool can_create) +{ + DBUG_ENTER("mrn_get_slot_data"); + st_mrn_slot_data *slot_data = + (st_mrn_slot_data*) *thd_ha_data(thd, mrn_hton_ptr); + if (slot_data == NULL) { + slot_data = (st_mrn_slot_data*) malloc(sizeof(st_mrn_slot_data)); + slot_data->first_alter_share = NULL; + *thd_ha_data(thd, mrn_hton_ptr) = (void *) slot_data; + pthread_mutex_lock(&mrn_allocated_thds_mutex); + if (my_hash_insert(&mrn_allocated_thds, (uchar*) thd)) + { + pthread_mutex_unlock(&mrn_allocated_thds_mutex); + free(slot_data); + DBUG_RETURN(NULL); + } + pthread_mutex_unlock(&mrn_allocated_thds_mutex); + } + DBUG_RETURN(slot_data); +} + +void mrn_clear_alter_share(THD *thd) +{ + DBUG_ENTER("mrn_clear_alter_share"); + st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, FALSE); + if (slot_data && slot_data->first_alter_share) + { + st_mrn_alter_share *tmp_alter_share; + st_mrn_alter_share *alter_share = slot_data->first_alter_share; + while (alter_share) + { + tmp_alter_share = alter_share->next; + mrn_q_free_table_share(alter_share->alter_share); + free(alter_share); + alter_share = tmp_alter_share; + } + slot_data->first_alter_share = NULL; + } + DBUG_VOID_RETURN; +} Modified: mrn_table.h (+18 -0) =================================================================== --- mrn_table.h 2011-11-25 13:26:52 +0000 (40d1812) +++ mrn_table.h 2011-11-26 06:39:01 +0000 (a0509a1) @@ -51,6 +51,19 @@ typedef struct st_mroonga_share bool wrapper_mode; } MRN_SHARE; +struct st_mrn_alter_share +{ + char path[FN_REFLEN + 1]; + TABLE_SHARE *alter_share; + st_mrn_alter_share *next; +}; + +struct st_mrn_slot_data +{ + int last_insert_record_id; + st_mrn_alter_share *first_alter_share; +}; + #define MRN_SET_WRAP_SHARE_KEY(share, table_share) /* table_share->keys = share->wrap_keys; \ @@ -88,9 +101,14 @@ int mrn_free_share_alloc(MRN_SHARE *share); int mrn_free_share(MRN_SHARE *share); TABLE_SHARE *mrn_get_table_share(TABLE_LIST *table_list, int *error); void mrn_free_table_share(TABLE_SHARE *share); +TABLE_SHARE *mrn_q_get_table_share(TABLE_LIST *table_list, const char *path, + int *error); +void mrn_q_free_table_share(TABLE_SHARE *share); KEY *mrn_create_key_info_for_table(MRN_SHARE *share, TABLE *table, int *error); void mrn_set_bitmap_by_key(MY_BITMAP *map, KEY *key_info); uint mrn_decode(uchar *buf_st, uchar *buf_ed, const uchar *st, const uchar *ed); +st_mrn_slot_data *mrn_get_slot_data(THD *thd, bool can_create); +void mrn_clear_alter_share(THD *thd); #endif /* _mrn_table_h */