From 5f1f2fc0e443f098af24d21f7d1ec1a8166a4030 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Sat, 15 Jun 2013 18:32:08 +0300 Subject: Applied all changes from Igor and Sanja --- storage/example/ha_example.cc | 206 ++++++------------------------------------ storage/example/ha_example.h | 20 ++-- 2 files changed, 40 insertions(+), 186 deletions(-) (limited to 'storage/example') diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index 98968d0b5b5..b37845bf9ec 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -107,17 +107,6 @@ static handler *example_create_handler(handlerton *hton, handlerton *example_hton; -/* Variables for example share methods */ - -/* - Hash used to track the number of open tables; variable for example share - methods -*/ -static HASH example_open_tables; - -/* The mutex used to init the hash; variable for example share methods */ -mysql_mutex_t example_mutex; - /** Structure for CREATE TABLE options (table options). @@ -199,20 +188,12 @@ ha_create_table_option example_field_option_list[]= Function we use in the creation of our hash to get key. */ -static uchar* example_get_key(EXAMPLE_SHARE *share, size_t *length, - my_bool not_used __attribute__((unused))) -{ - *length=share->table_name_length; - return (uchar*) share->table_name; -} - #ifdef HAVE_PSI_INTERFACE -static PSI_mutex_key ex_key_mutex_example, ex_key_mutex_EXAMPLE_SHARE_mutex; +static PSI_mutex_key ex_key_mutex_Example_share_mutex; static PSI_mutex_info all_example_mutexes[]= { - { &ex_key_mutex_example, "example", PSI_FLAG_GLOBAL}, - { &ex_key_mutex_EXAMPLE_SHARE_mutex, "EXAMPLE_SHARE::mutex", 0} + { &ex_key_mutex_Example_share_mutex, "Example_share::mutex", 0} }; static void init_example_psi_keys() @@ -220,15 +201,20 @@ static void init_example_psi_keys() const char* category= "example"; int count; - if (PSI_server == NULL) - return; - count= array_elements(all_example_mutexes); - PSI_server->register_mutex(category, all_example_mutexes, count); + mysql_mutex_register(category, all_example_mutexes, count); } #endif +Example_share::Example_share() +{ + thr_lock_init(&lock); + mysql_mutex_init(ex_key_mutex_Example_share_mutex, + &mutex, MY_MUTEX_INIT_FAST); +} + + static int example_init_func(void *p) { DBUG_ENTER("example_init_func"); @@ -238,10 +224,6 @@ static int example_init_func(void *p) #endif example_hton= (handlerton *)p; - mysql_mutex_init(ex_key_mutex_example, &example_mutex, MY_MUTEX_INIT_FAST); - (void) my_hash_init(&example_open_tables,system_charset_info,32,0,0, - (my_hash_get_key) example_get_key,0,0); - example_hton->state= SHOW_OPTION_YES; example_hton->create= example_create_handler; example_hton->flags= HTON_CAN_RECREATE; @@ -252,20 +234,6 @@ static int example_init_func(void *p) } -static int example_done_func(void *p) -{ - int error= 0; - DBUG_ENTER("example_done_func"); - - if (example_open_tables.records) - error= 1; - my_hash_free(&example_open_tables); - mysql_mutex_destroy(&example_mutex); - - DBUG_RETURN(error); -} - - /** @brief Example of simple lock controls. The "share" it creates is a @@ -274,71 +242,24 @@ static int example_done_func(void *p) they are needed to function. */ -static EXAMPLE_SHARE *get_share(const char *table_name, TABLE *table) +Example_share *ha_example::get_share() { - EXAMPLE_SHARE *share; - uint length; - char *tmp_name; + Example_share *tmp_share; - mysql_mutex_lock(&example_mutex); - length=(uint) strlen(table_name); + DBUG_ENTER("ha_example::get_share()"); - if (!(share=(EXAMPLE_SHARE*) my_hash_search(&example_open_tables, - (uchar*) table_name, - length))) + lock_shared_ha_data(); + if (!(tmp_share= static_cast(get_ha_share_ptr()))) { - if (!(share=(EXAMPLE_SHARE *) - my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), - &share, sizeof(*share), - &tmp_name, length+1, - NullS))) - { - mysql_mutex_unlock(&example_mutex); - return NULL; - } - - share->use_count=0; - share->table_name_length=length; - share->table_name=tmp_name; - strmov(share->table_name,table_name); - if (my_hash_insert(&example_open_tables, (uchar*) share)) - goto error; - thr_lock_init(&share->lock); - mysql_mutex_init(ex_key_mutex_EXAMPLE_SHARE_mutex, - &share->mutex, MY_MUTEX_INIT_FAST); - } - share->use_count++; - mysql_mutex_unlock(&example_mutex); - - return share; + tmp_share= new Example_share; + if (!tmp_share) + goto err; -error: - mysql_mutex_destroy(&share->mutex); - my_free(share); - - return NULL; -} - - -/** - @brief - Free lock controls. We call this whenever we close a table. If the table had - the last reference to the share, then we free memory associated with it. -*/ - -static int free_share(EXAMPLE_SHARE *share) -{ - mysql_mutex_lock(&example_mutex); - if (!--share->use_count) - { - my_hash_delete(&example_open_tables, (uchar*) share); - thr_lock_delete(&share->lock); - mysql_mutex_destroy(&share->mutex); - my_free(share); + set_ha_share_ptr(static_cast(tmp_share)); } - mysql_mutex_unlock(&example_mutex); - - return 0; +err: + unlock_shared_ha_data(); + DBUG_RETURN(tmp_share); } static handler* example_create_handler(handlerton *hton, @@ -400,7 +321,7 @@ int ha_example::open(const char *name, int mode, uint test_if_locked) { DBUG_ENTER("ha_example::open"); - if (!(share = get_share(name, table))) + if (!(share = get_share())) DBUG_RETURN(1); thr_lock_data_init(&share->lock,&lock,NULL); @@ -420,8 +341,7 @@ int ha_example::open(const char *name, int mode, uint test_if_locked) /** @brief - Closes a table. We call the free_share() function to free any resources - that we have allocated in the "shared" structure. + Closes a table. @details Called from sql_base.cc, sql_select.cc, and table.cc. In sql_select.cc it is @@ -437,7 +357,7 @@ int ha_example::open(const char *name, int mode, uint test_if_locked) int ha_example::close(void) { DBUG_ENTER("ha_example::close"); - DBUG_RETURN(free_share(share)); + DBUG_RETURN(0); } @@ -979,76 +899,6 @@ int ha_example::create(const char *name, TABLE *table_arg, } -/** - check_if_incompatible_data() called if ALTER TABLE can't detect otherwise - if new and old definition are compatible - - @details If there are no other explicit signs like changed number of - fields this function will be called by compare_tables() - (sql/sql_tables.cc) to decide should we rewrite whole table or only .frm - file. - -*/ - -bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info, - uint table_changes) -{ - ha_table_option_struct *param_old, *param_new; - DBUG_ENTER("ha_example::check_if_incompatible_data"); - /* - This example shows how custom engine specific table and field - options can be accessed from this function to be compared. - */ - param_new= info->option_struct; - DBUG_PRINT("info", ("new strparam: '%-.64s' ullparam: %llu enumparam: %u " - "boolparam: %u", - (param_new->strparam ? param_new->strparam : ""), - param_new->ullparam, param_new->enumparam, - param_new->boolparam)); - - param_old= table->s->option_struct; - DBUG_PRINT("info", ("old strparam: '%-.64s' ullparam: %llu enumparam: %u " - "boolparam: %u", - (param_old->strparam ? param_old->strparam : ""), - param_old->ullparam, param_old->enumparam, - param_old->boolparam)); - - /* - check important parameters: - for this example engine, we'll assume that changing ullparam or - boolparam requires a table to be rebuilt, while changing strparam - or enumparam - does not. - */ - if (param_new->ullparam != param_old->ullparam || - param_new->boolparam != param_old->boolparam) - DBUG_RETURN(COMPATIBLE_DATA_NO); - -#ifndef DBUG_OFF - for (uint i= 0; i < table->s->fields; i++) - { - ha_field_option_struct *f_old, *f_new; - f_old= table->s->field[i]->option_struct; - DBUG_ASSERT(f_old); - DBUG_PRINT("info", ("old field: %u old complex: '%-.64s'", i, - (f_old->complex_param_to_parse_it_in_engine ? - f_old->complex_param_to_parse_it_in_engine : - ""))); - if (info->fields_option_struct[i]) - { - f_new= info->fields_option_struct[i]; - DBUG_PRINT("info", ("old field: %u new complex: '%-.64s'", i, - (f_new->complex_param_to_parse_it_in_engine ? - f_new->complex_param_to_parse_it_in_engine : - ""))); - } - else - DBUG_PRINT("info", ("old field %i did not changed", i)); - } -#endif - - DBUG_RETURN(COMPATIBLE_DATA_YES); -} - struct st_mysql_storage_engine example_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; @@ -1126,7 +976,7 @@ mysql_declare_plugin(example) "Example storage engine", PLUGIN_LICENSE_GPL, example_init_func, /* Plugin Init */ - example_done_func, /* Plugin Deinit */ + NULL, /* Plugin Deinit */ 0x0001 /* 0.1 */, func_status, /* status variables */ example_system_variables, /* system variables */ @@ -1143,7 +993,7 @@ maria_declare_plugin(example) "Example storage engine", PLUGIN_LICENSE_GPL, example_init_func, /* Plugin Init */ - example_done_func, /* Plugin Deinit */ + NULL, /* Plugin Deinit */ 0x0001, /* version number (0.1) */ func_status, /* status variables */ example_system_variables, /* system variables */ diff --git a/storage/example/ha_example.h b/storage/example/ha_example.h index 9be370edfe3..361e4b3a848 100644 --- a/storage/example/ha_example.h +++ b/storage/example/ha_example.h @@ -42,15 +42,20 @@ #include "my_base.h" /* ha_rows */ /** @brief - EXAMPLE_SHARE is a structure that will be shared among all open handlers. + Example_share is a class that will be shared among all open handlers. This example implements the minimum of what you will probably need. */ -typedef struct st_example_share { - char *table_name; - uint table_name_length,use_count; +class Example_share : public Handler_share { +public: mysql_mutex_t mutex; THR_LOCK lock; -} EXAMPLE_SHARE; + Example_share(); + ~Example_share() + { + thr_lock_delete(&lock); + mysql_mutex_destroy(&mutex); + } +}; /** @brief Class definition for the storage engine @@ -58,7 +63,8 @@ typedef struct st_example_share { class ha_example: public handler { THR_LOCK_DATA lock; ///< MySQL lock - EXAMPLE_SHARE *share; ///< Shared lock info + Example_share *share; ///< Shared lock info + Example_share *get_share(); ///< Get the share public: ha_example(handlerton *hton, TABLE_SHARE *table_arg); @@ -246,8 +252,6 @@ public: int delete_table(const char *from); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); ///< required - bool check_if_incompatible_data(HA_CREATE_INFO *info, - uint table_changes); THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type); ///< required -- cgit v1.2.1 From f672d6b7d8b2a2f4570d5407481b3cdaaaa44e43 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 12 Jul 2013 11:36:54 +0200 Subject: restore ha_example::check_if_incompatible_data(), create_info->fields_option_struct, create_info->indexes_option_struct lost in the merge. add test cases. --- storage/example/ha_example.cc | 83 +++++++++++++++++++++++++++++++++++++++++++ storage/example/ha_example.h | 2 ++ 2 files changed, 85 insertions(+) (limited to 'storage/example') diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index b37845bf9ec..ac36f0bc864 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -899,6 +899,89 @@ int ha_example::create(const char *name, TABLE *table_arg, } +/** + check_if_incompatible_data() called if ALTER TABLE can't detect otherwise + if new and old definition are compatible + + @details If there are no other explicit signs like changed number of + fields this function will be called by compare_tables() + (sql/sql_tables.cc) to decide should we rewrite whole table or only .frm + file. + +*/ + +bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info, + uint table_changes) +{ + ha_table_option_struct *param_old, *param_new; + DBUG_ENTER("ha_example::check_if_incompatible_data"); + /* + This example shows how custom engine specific table and field + options can be accessed from this function to be compared. + */ + param_new= info->option_struct; + DBUG_PRINT("info", ("new strparam: '%-.64s' ullparam: %llu enumparam: %u " + "boolparam: %u", + (param_new->strparam ? param_new->strparam : ""), + param_new->ullparam, param_new->enumparam, + param_new->boolparam)); + + param_old= table->s->option_struct; + DBUG_PRINT("info", ("old strparam: '%-.64s' ullparam: %llu enumparam: %u " + "boolparam: %u", + (param_old->strparam ? param_old->strparam : ""), + param_old->ullparam, param_old->enumparam, + param_old->boolparam)); + + /* + check important parameters: + for this example engine, we'll assume that changing ullparam or + boolparam requires a table to be rebuilt, while changing strparam + or enumparam - does not. + + For debugging purposes we'll announce this to the client + (don't do it in your engine!) + + */ + if (param_new->ullparam != param_old->ullparam) + { + push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE, + ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: ULL %llu -> %llu", + param_old->ullparam, param_new->ullparam); + DBUG_RETURN(COMPATIBLE_DATA_NO); + } + + if (param_new->boolparam != param_old->boolparam) + { + push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE, + ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: YESNO %u -> %u", + param_old->boolparam, param_new->boolparam); + DBUG_RETURN(COMPATIBLE_DATA_NO); + } + +#ifndef DBUG_OFF + for (uint i= 0; i < table->s->fields; i++) + { + ha_field_option_struct *f_old, *f_new; + f_old= table->s->field[i]->option_struct; + DBUG_ASSERT(f_old); + if (info->fields_option_struct[i]) + { + f_new= info->fields_option_struct[i]; + push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE, + ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: Field %`s COMPLEX '%s' -> '%s'", + table->s->field[i]->field_name, + f_old->complex_param_to_parse_it_in_engine, + f_new->complex_param_to_parse_it_in_engine); + } + else + DBUG_PRINT("info", ("old field %i did not changed", i)); + } +#endif + + DBUG_RETURN(COMPATIBLE_DATA_YES); +} + struct st_mysql_storage_engine example_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; diff --git a/storage/example/ha_example.h b/storage/example/ha_example.h index 361e4b3a848..5a66d15e54f 100644 --- a/storage/example/ha_example.h +++ b/storage/example/ha_example.h @@ -252,6 +252,8 @@ public: int delete_table(const char *from); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); ///< required + bool check_if_incompatible_data(HA_CREATE_INFO *info, + uint table_changes); THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type); ///< required -- cgit v1.2.1