diff options
author | unknown <acurtis@xiphis.org> | 2005-12-21 10:18:40 -0800 |
---|---|---|
committer | unknown <acurtis@xiphis.org> | 2005-12-21 10:18:40 -0800 |
commit | 613dd50a33ac3e64073abdbdae66ce3a93e69e30 (patch) | |
tree | d777ca5871199d389af93e8cbe06e1bdbc16a10b /sql/sql_plugin.cc | |
parent | 9c81773b37a5ec1a689632e3161ae6b9d1fdeb46 (diff) | |
download | mariadb-git-613dd50a33ac3e64073abdbdae66ce3a93e69e30.tar.gz |
Finalize storage engine plugins
Give BerkeleyDB savepoints
Remove "enum db_type" from most of the code
storage/example/ha_example.h:
Rename: sql/examples/ha_example.h -> storage/example/ha_example.h
storage/csv/ha_tina.h:
Rename: sql/examples/ha_tina.h -> storage/csv/ha_tina.h
config/ac-macros/storage.m4:
if hton name is "no", then we don't install it as a builtin
configure.in:
pluggable changes
include/plugin.h:
version field
mysql-test/r/bdb.result:
savepoint results copied from innodb test
mysql-test/r/information_schema.result:
PLUGINS information schema
mysql-test/r/information_schema_db.result:
PLUGINS information schema
mysql-test/t/bdb.test:
savepoint test copied from innodb test
sql/Makefile.am:
tina and example are not here anymore
sql/authors.h:
minor tweek
sql/ha_archive.cc:
remove unwanted handlerton entries
sql/ha_berkeley.cc:
remove unwanted handlerton entries
support for savepoints
changes to show logs
sql/ha_blackhole.cc:
remove unwanted handlerton entries
sql/ha_federated.cc:
remove unwanted handlerton entries
sql/ha_heap.cc:
remove unwanted handlerton entries
sql/ha_innodb.cc:
remove unwanted handlerton entries
changes for show status
sql/ha_myisam.cc:
remove unwanted handlerton entries
sql/ha_myisammrg.cc:
remove unwanted handlerton entries
sql/ha_ndbcluster.cc:
remove unwanted handlerton entries
changes to stat_print
sql/ha_partition.cc:
remove unwanted handlerton entries
bye bye enum db_type
sql/ha_partition.h:
bye bye enum db_type
sql/handler.cc:
remove unwanted handlerton entries
bye bye enum db_type
sql/handler.h:
remove unwanted handlerton entries
bye bye enum db_type
changes to stat_print_fn
sql/item_sum.cc:
bye bye enum db_type
sql/log.cc:
remove unwanted handlerton entries
sql/mysql_priv.h:
bye bye enum db_type
sql/mysqld.cc:
bye bye enum db_type
reorder plugin initialization
sql/set_var.cc:
bye bye enum db_type
sql/set_var.h:
bye bye enum db_type
sql/sql_base.cc:
bye bye enum db_type
sql/sql_cache.cc:
bye bye enum db_type
sql/sql_class.h:
bye bye enum db_type
sql/sql_delete.cc:
bye bye enum db_type
sql/sql_insert.cc:
bye bye enum db_type
sql/sql_lex.h:
show plugin
sql/sql_parse.cc:
bye bye enum db_type
sql/sql_partition.cc:
bye bye enum db_type
sql/sql_plugin.cc:
loadable storage engines
sql/sql_plugin.h:
loadable storage engines
sql/sql_rename.cc:
bye bye enum db_type
sql/sql_select.cc:
bye bye enum db_type
sql/sql_show.cc:
SHOW PLUGIN
PLUGINS information schema
changes to show engines
sql/sql_table.cc:
bye bye enum db_type
sql/sql_view.cc:
bye bye enum db_type
sql/sql_view.h:
bye bye enum db_type
sql/sql_yacc.yy:
bye bye enum db_type
sql/table.cc:
bye bye enum db_type
sql/table.h:
bye bye enum db_type
sql/unireg.cc:
bye bye enum db_type
storage/csv/ha_tina.cc:
make tina into a loadable plugin
storage/example/ha_example.cc:
make into a plugin
storage/csv/Makefile.am:
New BitKeeper file ``storage/csv/Makefile.am''
storage/example/Makefile.am:
New BitKeeper file ``storage/example/Makefile.am''
Diffstat (limited to 'sql/sql_plugin.cc')
-rw-r--r-- | sql/sql_plugin.cc | 238 |
1 files changed, 182 insertions, 56 deletions
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 7e78b58e6cf..591289f6ee1 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -33,7 +33,6 @@ static HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM]; static rw_lock_t THR_LOCK_plugin; static bool initialized= 0; - static struct st_plugin_dl *plugin_dl_find(LEX_STRING *dl) { uint i; @@ -348,6 +347,43 @@ void plugin_unlock(struct st_plugin_int *plugin) } +static int plugin_initialize(struct st_plugin_int *plugin) +{ + DBUG_ENTER("plugin_initialize"); + + if (plugin->plugin->init) + { + if (plugin->plugin->init()) + { + sql_print_error("Plugin '%s' init function returned error.", + plugin->name.str); + DBUG_PRINT("warning", ("Plugin '%s' init function returned error.", + plugin->name.str)) + goto err; + } + } + + switch (plugin->plugin->type) + { + case MYSQL_STORAGE_ENGINE_PLUGIN: + if (ha_initialize_handlerton((handlerton*) plugin->plugin->info)) + { + sql_print_error("Plugin '%s' handlerton init returned error.", + plugin->name.str); + DBUG_PRINT("warning", ("Plugin '%s' handlerton init returned error.", + plugin->name.str)) + goto err; + } + break; + default: + break; + } + + DBUG_RETURN(0); +err: + DBUG_RETURN(1); +} + static void plugin_call_initializer(void) { uint i; @@ -356,20 +392,13 @@ static void plugin_call_initializer(void) { struct st_plugin_int *tmp= dynamic_element(&plugin_array, i, struct st_plugin_int *); - if (tmp->state == PLUGIN_IS_UNINITIALIZED && tmp->plugin->init) + if (tmp->state == PLUGIN_IS_UNINITIALIZED) { - DBUG_PRINT("info", ("Initializing plugin: '%s'", tmp->name.str)); - if (tmp->plugin->init()) - { - sql_print_error("Plugin '%s' init function returned error.", - tmp->name.str); - DBUG_PRINT("warning", ("Plugin '%s' init function returned error.", - tmp->name.str)) + if (plugin_initialize(tmp)) plugin_del(&tmp->name); - } + else + tmp->state= PLUGIN_IS_READY; } - if (tmp->state == PLUGIN_IS_UNINITIALIZED) - tmp->state= PLUGIN_IS_READY; } DBUG_VOID_RETURN; } @@ -410,42 +439,84 @@ static byte *get_hash_key(const byte *buff, uint *length, } -void plugin_init(void) +int plugin_init(void) +{ + int i; + DBUG_ENTER("plugin_init"); + + if (initialized) + DBUG_RETURN(0); + + my_rwlock_init(&THR_LOCK_plugin, NULL); + + if (my_init_dynamic_array(&plugin_dl_array, + sizeof(struct st_plugin_dl),16,16) || + my_init_dynamic_array(&plugin_array, + sizeof(struct st_plugin_int),16,16)) + goto err; + + for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++) + { + if (hash_init(&plugin_hash[i], system_charset_info, 16, 0, 0, + get_hash_key, NULL, 0)) + goto err; + } + + initialized= 1; + + DBUG_RETURN(0); + +err: + DBUG_RETURN(1); +} + + +my_bool plugin_register_builtin(struct st_mysql_plugin *plugin) +{ + struct st_plugin_int tmp; + DBUG_ENTER("plugin_register_builtin"); + + tmp.plugin= plugin; + tmp.name.str= (char *)plugin->name; + tmp.name.length= strlen(plugin->name); + tmp.state= PLUGIN_IS_UNINITIALIZED; + + /* Cannot be unloaded */ + tmp.ref_count= 1; + tmp.plugin_dl= 0; + + if (insert_dynamic(&plugin_array, (gptr)&tmp)) + DBUG_RETURN(1); + + if (my_hash_insert(&plugin_hash[plugin->type], + (byte*)dynamic_element(&plugin_array, + plugin_array.elements - 1, + struct st_plugin_int *))) + DBUG_RETURN(1); + + DBUG_RETURN(0); +} + + +void plugin_load(void) { TABLE_LIST tables; TABLE *table; READ_RECORD read_record_info; int error, i; MEM_ROOT mem; - DBUG_ENTER("plugin_init"); - if (initialized) - DBUG_VOID_RETURN; - my_rwlock_init(&THR_LOCK_plugin, NULL); - THD *new_thd = new THD; - if (!new_thd || - my_init_dynamic_array(&plugin_dl_array,sizeof(struct st_plugin_dl),16,16) || - my_init_dynamic_array(&plugin_array,sizeof(struct st_plugin_int),16,16)) + THD *new_thd; + DBUG_ENTER("plugin_load"); + + DBUG_ASSERT(initialized); + + if (!(new_thd= new THD)) { sql_print_error("Can't allocate memory for plugin structures"); delete new_thd; - delete_dynamic(&plugin_dl_array); - delete_dynamic(&plugin_array); DBUG_VOID_RETURN; } - for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++) - { - if (hash_init(&plugin_hash[i], system_charset_info, 16, 0, 0, - get_hash_key, NULL, 0)) - { - sql_print_error("Can't allocate memory for plugin structures"); - delete new_thd; - delete_dynamic(&plugin_dl_array); - delete_dynamic(&plugin_array); - DBUG_VOID_RETURN; - } - } init_sql_alloc(&mem, 1024, 0); - initialized= 1; new_thd->thread_stack= (char*) &tables; new_thd->store_globals(); new_thd->db= my_strdup("mysql", MYF(0)); @@ -458,10 +529,6 @@ void plugin_init(void) { DBUG_PRINT("error",("Can't open plugin table")); sql_print_error("Can't open the mysql.plugin table. Please run the mysql_install_db script to create it."); - delete_dynamic(&plugin_dl_array); - delete_dynamic(&plugin_array); - for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++) - hash_free(&plugin_hash[i]); goto end; } table= tables.table; @@ -530,27 +597,31 @@ my_bool mysql_install_plugin(THD *thd, LEX_STRING *name, LEX_STRING *dl) int error; struct st_plugin_int *tmp; DBUG_ENTER("mysql_install_plugin"); + bzero(&tables, sizeof(tables)); tables.db= (char *)"mysql"; tables.table_name= tables.alias= (char *)"plugin"; if (check_table_access(thd, INSERT_ACL, &tables, 0)) DBUG_RETURN(TRUE); + + /* need to open before acquiring THR_LOCK_plugin or it will deadlock */ + if (! (table = open_ltable(thd, &tables, TL_WRITE))) + DBUG_RETURN(TRUE); + rw_wrlock(&THR_LOCK_plugin); if (plugin_add(name, dl, REPORT_TO_USER)) goto err; tmp= plugin_find_internal(name, MYSQL_ANY_PLUGIN); - if (tmp->plugin->init) + + if (plugin_initialize(tmp)) { - if (tmp->plugin->init()) - { - my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str, - "Plugin initialization function failed."); - goto err; - } - tmp->state= PLUGIN_IS_READY; + my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str, + "Plugin initialization function failed."); + goto err; } - if (! (table = open_ltable(thd, &tables, TL_WRITE))) - goto deinit; + + tmp->state= PLUGIN_IS_READY; + restore_record(table, s->default_values); table->field[0]->store(name->str, name->length, system_charset_info); table->field[1]->store(dl->str, dl->length, files_charset_info); @@ -560,6 +631,7 @@ my_bool mysql_install_plugin(THD *thd, LEX_STRING *name, LEX_STRING *dl) table->file->print_error(error, MYF(0)); goto deinit; } + rw_unlock(&THR_LOCK_plugin); DBUG_RETURN(FALSE); deinit: @@ -578,12 +650,29 @@ my_bool mysql_uninstall_plugin(THD *thd, LEX_STRING *name) TABLE_LIST tables; struct st_plugin_int *plugin; DBUG_ENTER("mysql_uninstall_plugin"); + + bzero(&tables, sizeof(tables)); + tables.db= (char *)"mysql"; + tables.table_name= tables.alias= (char *)"plugin"; + + /* need to open before acquiring THR_LOCK_plugin or it will deadlock */ + if (! (table= open_ltable(thd, &tables, TL_WRITE))) + DBUG_RETURN(TRUE); + rw_wrlock(&THR_LOCK_plugin); - if (! (plugin= plugin_find_internal(name, MYSQL_ANY_PLUGIN))) + if (!(plugin= plugin_find_internal(name, MYSQL_ANY_PLUGIN))) { my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str); goto err; } + if (!plugin->plugin_dl) + { + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, + "Built-in plugins cannot be deleted,."); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str); + goto err; + } + if (plugin->ref_count) { plugin->state= PLUGIN_IS_DELETED; @@ -596,11 +685,7 @@ my_bool mysql_uninstall_plugin(THD *thd, LEX_STRING *name) plugin->plugin->deinit(); plugin_del(name); } - bzero(&tables, sizeof(tables)); - tables.db= (char *)"mysql"; - tables.table_name= tables.alias= (char *)"plugin"; - if (! (table= open_ltable(thd, &tables, TL_WRITE))) - goto err; + table->field[0]->store(name->str, name->length, system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (! table->file->index_read_idx(table->record[0], 0, @@ -621,3 +706,44 @@ err: rw_unlock(&THR_LOCK_plugin); DBUG_RETURN(TRUE); } + + +my_bool plugin_foreach(THD *thd, plugin_foreach_func *func, + int type, void *arg) +{ + uint idx; + struct st_plugin_int *plugin; + DBUG_ENTER("mysql_uninstall_plugin"); + rw_rdlock(&THR_LOCK_plugin); + + if (type == MYSQL_ANY_PLUGIN) + { + for (idx= 0; idx < plugin_array.elements; idx++) + { + plugin= dynamic_element(&plugin_array, idx, struct st_plugin_int *); + + /* FREED records may have garbage pointers */ + if ((plugin->state != PLUGIN_IS_FREED) && + func(thd, plugin, arg)) + goto err; + } + } + else + { + HASH *hash= &plugin_hash[type]; + for (idx= 0; idx < hash->records; idx++) + { + plugin= (struct st_plugin_int *) hash_element(hash, idx); + if ((plugin->state != PLUGIN_IS_FREED) && + (plugin->state != PLUGIN_IS_DELETED) && + func(thd, plugin, arg)) + goto err; + } + } + + rw_unlock(&THR_LOCK_plugin); + DBUG_RETURN(FALSE); +err: + rw_unlock(&THR_LOCK_plugin); + DBUG_RETURN(TRUE); +} |