Below is the list of changes that have just been committed into a local
5.1 repository of antony. When antony does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.1995 05/12/01 19:24:40 acurtis@stripped +14 -0
Storage engines as a shared library plugin support
storage/example/Makefile.am
1.1 05/12/01 19:24:35 acurtis@stripped +38 -0
New BitKeeper file ``storage/example/Makefile.am''
storage/csv/Makefile.am
1.1 05/12/01 19:24:35 acurtis@stripped +38 -0
New BitKeeper file ``storage/csv/Makefile.am''
storage/example/Makefile.am
1.0 05/12/01 19:24:35 acurtis@stripped +0 -0
BitKeeper file /home/antony/work3/mysql-5.1-plugable-2/storage/example/Makefile.am
storage/csv/ha_tina.cc
1.26 05/12/01 19:24:35 acurtis@stripped +46 -21
convert into a plugin
storage/csv/Makefile.am
1.0 05/12/01 19:24:35 acurtis@stripped +0 -0
BitKeeper file /home/antony/work3/mysql-5.1-plugable-2/storage/csv/Makefile.am
sql/sql_show.cc
1.284 05/12/01 19:24:35 acurtis@stripped +18 -11
changes to handlerton enumeration
sql/sql_plugin.cc
1.4 05/12/01 19:24:35 acurtis@stripped +43 -1
installing a storage engine plugin installs it
sql/share/errmsg.txt
1.57 05/12/01 19:24:35 acurtis@stripped +6 -0
new error messages
sql/handler.cc
1.196 05/12/01 19:24:35 acurtis@stripped +291 -100
changes to handlerton enumeration
functions to install and uninstall
sql/Makefile.am
1.124 05/12/01 19:24:35 acurtis@stripped +1 -3
remove tina and example
include/my_base.h
1.75 05/12/01 19:24:35 acurtis@stripped +2 -1
at uninstall, panic is called with HA_PANIC_TRY_CLOSE.
The storage engine can abort the uninstall.
configure.in
1.314 05/12/01 19:24:34 acurtis@stripped +8 -2
pluggable changes
config/ac-macros/storage.m4
1.2 05/12/01 19:24:34 acurtis@stripped +7 -4
if hton name is "no", then we don't install it as a builtin
storage/csv/ha_tina.h
1.10 05/12/01 16:11:14 acurtis@stripped +0 -0
Rename: sql/examples/ha_tina.h -> storage/csv/ha_tina.h
storage/csv/ha_tina.cc
1.25 05/12/01 16:11:14 acurtis@stripped +0 -0
Rename: sql/examples/ha_tina.cc -> storage/csv/ha_tina.cc
storage/example/ha_example.h
1.13 05/12/01 16:10:59 acurtis@stripped +0 -0
Rename: sql/examples/ha_example.h -> storage/example/ha_example.h
storage/example/ha_example.cc
1.24 05/12/01 16:10:59 acurtis@stripped +0 -0
Rename: sql/examples/ha_example.cc -> storage/example/ha_example.cc
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: acurtis
# Host: xiphis.org
# Root: /home/antony/work3/mysql-5.1-plugable-2
--- 1.313/configure.in 2005-11-24 05:23:10 -08:00
+++ 1.314/configure.in 2005-12-01 19:24:34 -08:00
@@ -2411,9 +2411,15 @@
MYSQL_STORAGE_ENGINE(berkeley,,berkeley-db,,,,storage/bdb,,,[
MYSQL_SETUP_BERKELEY_DB
])
-MYSQL_STORAGE_ENGINE(example)
+dnl MYSQL_STORAGE_ENGINE(example)
+MYSQL_STORAGE_ENGINE(example,,,,,no,storage/example,,,[
+ AC_CONFIG_FILES(storage/example/Makefile)
+])
MYSQL_STORAGE_ENGINE(archive)
-MYSQL_STORAGE_ENGINE(csv,,,,,tina_hton,,ha_tina.o)
+dnl MYSQL_STORAGE_ENGINE(csv,,,,,tina_hton,,ha_tina.o)
+MYSQL_STORAGE_ENGINE(csv,,,,,no,storage/csv,,,[
+ AC_CONFIG_FILES(storage/csv/Makefile)
+])
MYSQL_STORAGE_ENGINE(blackhole)
MYSQL_STORAGE_ENGINE(federated)
MYSQL_STORAGE_ENGINE(ndbcluster,,ndbcluster,,,,storage/ndb,,,[
--- 1.74/include/my_base.h 2005-11-28 11:07:09 -08:00
+++ 1.75/include/my_base.h 2005-12-01 19:24:35 -08:00
@@ -160,7 +160,8 @@
enum ha_panic_function {
HA_PANIC_CLOSE, /* Close all databases */
HA_PANIC_WRITE, /* Unlock and write status */
- HA_PANIC_READ /* Lock and read keyinfo */
+ HA_PANIC_READ, /* Lock and read keyinfo */
+ HA_PANIC_TRY_CLOSE, /* Close all if no open instance */
};
/* The following is parameter to ha_create(); keytypes */
--- 1.123/sql/Makefile.am 2005-11-25 20:26:19 -08:00
+++ 1.124/sql/Makefile.am 2005-12-01 19:24:35 -08:00
@@ -101,9 +101,7 @@
ha_innodb.h ha_berkeley.h ha_archive.h \
ha_blackhole.cc ha_federated.cc ha_ndbcluster.cc \
ha_blackhole.h ha_federated.h ha_ndbcluster.h \
- ha_partition.cc ha_partition.h \
- examples/ha_tina.cc examples/ha_example.cc \
- examples/ha_tina.h examples/ha_example.h
+ ha_partition.cc ha_partition.h
mysqld_DEPENDENCIES = @mysql_se_objs@
gen_lex_hash_SOURCES = gen_lex_hash.cc
gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS)
--- 1.195/sql/handler.cc 2005-11-28 11:07:09 -08:00
+++ 1.196/sql/handler.cc 2005-12-01 19:24:35 -08:00
@@ -39,6 +39,8 @@
#endif
extern handlerton *sys_table_types[];
+HASH handlers;
+rw_lock_t LOCK_handlers;
/* static functions defined in this file */
@@ -78,22 +80,23 @@
{
THD *thd= current_thd;
show_table_alias_st *table_alias;
- handlerton **types;
+ handlerton *types;
if (thd && !my_strnncoll(&my_charset_latin1,
(const uchar *)name, namelen,
(const uchar *)"DEFAULT", 7))
return (enum db_type) thd->variables.table_type;
+ rw_rdlock(&LOCK_handlers);
retest:
- for (types= sys_table_types; *types; types++)
+ if ((types= (handlerton *) hash_search(&handlers, (byte*) name, namelen)))
{
- if ((!my_strnncoll(&my_charset_latin1,
- (const uchar *)name, namelen,
- (const uchar *)(*types)->name,
- strlen((*types)->name))) &&
- !((*types)->flags & HTON_NOT_USER_SELECTABLE))
- return (enum db_type) (*types)->db_type;
+ if (!(types->flags & HTON_NOT_USER_SELECTABLE))
+ {
+ enum db_type db_type= types->db_type;
+ rw_unlock(&LOCK_handlers);
+ return db_type;
+ }
}
/*
@@ -112,43 +115,62 @@
}
}
+ rw_unlock(&LOCK_handlers);
return DB_TYPE_UNKNOWN;
}
const char *ha_get_storage_engine(enum db_type db_type)
{
- handlerton **types;
- for (types= sys_table_types; *types; types++)
+ const char *name= "*NONE*";
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
{
- if (db_type == (*types)->db_type)
- return (*types)->name;
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (db_type == types->db_type)
+ {
+ name= types->name;
+ break;
+ }
}
- return "*NONE*";
+ rw_unlock(&LOCK_handlers);
+ return name;
}
bool ha_check_storage_engine_flag(enum db_type db_type, uint32 flag)
{
- handlerton **types;
- for (types= sys_table_types; *types; types++)
+ bool check= FALSE;
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
{
- if (db_type == (*types)->db_type)
- return test((*types)->flags & flag);
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (db_type == types->db_type)
+ {
+ check= test(types->flags & flag);
+ break;
+ }
}
- return FALSE; // No matching engine
+ rw_unlock(&LOCK_handlers);
+ return check;
}
my_bool ha_storage_engine_is_enabled(enum db_type database_type)
{
- handlerton **types;
- for (types= sys_table_types; *types; types++)
+ bool enabled= FALSE;
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
{
- if (database_type == (*types)->db_type)
- return ((*types)->state == SHOW_OPTION_YES) ? TRUE : FALSE;
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (database_type == types->db_type)
+ {
+ enabled= (types->state == SHOW_OPTION_YES);
+ break;
+ }
}
- return FALSE;
+ rw_unlock(&LOCK_handlers);
+ return enabled;
}
@@ -193,7 +215,6 @@
enum db_type db_type)
{
handler *file= NULL;
- handlerton **types;
/*
handlers are allocated with new in the handlerton create() function
we need to set the thd mem_root for these to be allocated correctly
@@ -201,15 +222,19 @@
THD *thd= current_thd;
MEM_ROOT *thd_save_mem_root= thd->mem_root;
thd->mem_root= alloc;
- for (types= sys_table_types; *types; types++)
+
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
{
- if (db_type == (*types)->db_type && (*types)->create)
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (db_type == types->db_type && types->create)
{
- file= ((*types)->state == SHOW_OPTION_YES) ?
- (*types)->create(share) : NULL;
+ file= (types->state == SHOW_OPTION_YES) ?
+ types->create(share) : NULL;
break;
}
}
+ rw_unlock(&LOCK_handlers);
thd->mem_root= thd_save_mem_root;
if (!file)
@@ -351,6 +376,13 @@
total_ha_2pc++;
}
+static byte* handler_get_key(handlerton *hton,uint *length,
+ my_bool not_used __attribute__((unused)))
+{
+ *length=(uint) strlen(hton->name);
+ return (byte*) hton->name;
+}
+
int ha_init()
{
int error= 0;
@@ -361,15 +393,26 @@
if (ha_init_errors())
return 1;
+ my_rwlock_init(&LOCK_handlers, NULL);
+
+ if (hash_init(&handlers, system_charset_info, 16, 0, 0,
+ (hash_get_key) handler_get_key, 0, 0))
+ return 1;
+
/*
We now initialize everything here.
*/
for (types= sys_table_types; *types; types++)
{
if (!(*types)->init || !(*types)->init())
- ha_was_inited_ok(types);
+ ha_was_inited_ok(types);
else
(*types)->state= SHOW_OPTION_DISABLED;
+ if (my_hash_insert(&handlers, (const byte *)*types))
+ {
+ sql_print_error("Fatal error: OOM while initializing storage engines");
+ return 1;
+ }
}
DBUG_ASSERT(total_ha < MAX_HA);
@@ -389,37 +432,48 @@
int ha_panic(enum ha_panic_function flag)
{
int error=0;
- handlerton **types;
+ uint index;
- for (types= sys_table_types; *types; types++)
+ for (index= 0; index < handlers.records; index++)
{
- if ((*types)->state == SHOW_OPTION_YES && (*types)->panic)
- error|= (*types)->panic(flag);
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (types->state == SHOW_OPTION_YES && types->panic)
+ error|= types->panic(flag);
}
- if (ha_finish_errors())
+ if (flag == HA_PANIC_CLOSE && ha_finish_errors())
error= 1;
+ if (flag == HA_PANIC_CLOSE && !error)
+ {
+ hash_free(&handlers);
+ rwlock_destroy(&LOCK_handlers);
+ }
return error;
} /* ha_panic */
void ha_drop_database(char* path)
{
- handlerton **types;
-
- for (types= sys_table_types; *types; types++)
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
{
- if ((*types)->state == SHOW_OPTION_YES && (*types)->drop_database)
- (*types)->drop_database(path);
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (types->state == SHOW_OPTION_YES && types->drop_database)
+ types->drop_database(path);
}
+ rw_unlock(&LOCK_handlers);
}
/* don't bother to rollback here, it's done already */
void ha_close_connection(THD* thd)
{
- handlerton **types;
- for (types= sys_table_types; *types; types++)
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
+ {
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
/* XXX Maybe do a rollback if close_connection == NULL ? */
- if (thd->ha_data[(*types)->slot] && (*types)->close_connection)
- (*types)->close_connection(thd);
+ if (thd->ha_data[types->slot] && types->close_connection)
+ types->close_connection(thd);
+ }
+ rw_unlock(&LOCK_handlers);
}
/* ========================================================================
@@ -731,18 +785,20 @@
int ha_commit_or_rollback_by_xid(XID *xid, bool commit)
{
- handlerton **types;
int res= 1;
- for (types= sys_table_types; *types; types++)
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
{
- if ((*types)->state == SHOW_OPTION_YES && (*types)->recover)
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (types->state == SHOW_OPTION_YES && types->recover)
{
- if ((*(commit ? (*types)->commit_by_xid :
- (*types)->rollback_by_xid))(xid));
+ if ((*(commit ? types->commit_by_xid :
+ types->rollback_by_xid))(xid));
res= 0;
}
}
+ rw_unlock(&LOCK_handlers);
return res;
}
@@ -822,7 +878,6 @@
int ha_recover(HASH *commit_list)
{
int len, got, found_foreign_xids=0, found_my_xids=0;
- handlerton **types;
XID *list=0;
bool dry_run=(commit_list==0 && tc_heuristic_recover==0);
DBUG_ENTER("ha_recover");
@@ -858,14 +913,16 @@
DBUG_RETURN(1);
}
- for (types= sys_table_types; *types; types++)
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
{
- if ((*types)->state != SHOW_OPTION_YES || !(*types)->recover)
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (types->state != SHOW_OPTION_YES || !types->recover)
continue;
- while ((got=(*(*types)->recover)(list, len)) > 0 )
+ while ((got=(*types->recover)(list, len)) > 0 )
{
sql_print_information("Found %d prepared transaction(s) in %s",
- got, (*types)->name);
+ got, types->name);
for (int i=0; i < got; i ++)
{
my_xid x=list[i].get_my_xid();
@@ -893,7 +950,7 @@
char buf[XIDDATASIZE*4+6]; // see xid_to_str
sql_print_information("commit xid %s", xid_to_str(buf, list+i));
#endif
- (*(*types)->commit_by_xid)(list+i);
+ (*types->commit_by_xid)(list+i);
}
else
{
@@ -901,13 +958,14 @@
char buf[XIDDATASIZE*4+6]; // see xid_to_str
sql_print_information("rollback xid %s", xid_to_str(buf, list+i));
#endif
- (*(*types)->rollback_by_xid)(list+i);
+ (*types->rollback_by_xid)(list+i);
}
}
if (got < len)
break;
}
}
+ rw_unlock(&LOCK_handlers);
my_free((gptr)list, MYF(0));
if (found_foreign_xids)
sql_print_warning("Found %d prepared XA transactions", found_foreign_xids);
@@ -995,14 +1053,15 @@
int ha_release_temporary_latches(THD *thd)
{
- handlerton **types;
-
- for (types= sys_table_types; *types; types++)
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
{
- if ((*types)->state == SHOW_OPTION_YES &&
- (*types)->release_temporary_latches)
- (*types)->release_temporary_latches(thd);
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (types->state == SHOW_OPTION_YES &&
+ types->release_temporary_latches)
+ types->release_temporary_latches(thd);
}
+ rw_unlock(&LOCK_handlers);
return 0;
}
@@ -1014,13 +1073,14 @@
int ha_update_statistics()
{
- handlerton **types;
-
- for (types= sys_table_types; *types; types++)
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
{
- if ((*types)->state == SHOW_OPTION_YES && (*types)->update_statistics)
- (*types)->update_statistics();
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (types->state == SHOW_OPTION_YES && types->update_statistics)
+ types->update_statistics();
}
+ rw_unlock(&LOCK_handlers);
return 0;
}
@@ -1132,17 +1192,19 @@
int ha_start_consistent_snapshot(THD *thd)
{
bool warn= true;
- handlerton **types;
- for (types= sys_table_types; *types; types++)
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
{
- if ((*types)->state == SHOW_OPTION_YES &&
- (*types)->start_consistent_snapshot)
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (types->state == SHOW_OPTION_YES &&
+ types->start_consistent_snapshot)
{
- (*types)->start_consistent_snapshot(thd);
+ types->start_consistent_snapshot(thd);
warn= false; /* hope user is using engine */
}
}
+ rw_unlock(&LOCK_handlers);
/*
Same idea as when one wants to CREATE TABLE in one engine which does not
exist:
@@ -1158,18 +1220,20 @@
bool ha_flush_logs(enum db_type db_type)
{
bool result=0;
- handlerton **types;
- for (types= sys_table_types; *types; types++)
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
{
- if ((*types)->state == SHOW_OPTION_YES &&
- (db_type == DB_TYPE_DEFAULT || db_type == (*types)->db_type) &&
- (*types)->flush_logs)
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (types->state == SHOW_OPTION_YES &&
+ (db_type == DB_TYPE_DEFAULT || db_type == types->db_type) &&
+ types->flush_logs)
{
- if ((*types)->flush_logs())
+ if (types->flush_logs())
result= 1;
}
}
+ rw_unlock(&LOCK_handlers);
return result;
}
@@ -2491,7 +2555,6 @@
MEM_ROOT *mem_root= current_thd->mem_root;
if (!known_extensions.type_names || mysys_usage_id != known_extensions_id)
{
- handlerton **types;
List<char> found_exts;
List_iterator_fast<char> it(found_exts);
const char **ext, *old_ext;
@@ -2499,12 +2562,14 @@
known_extensions_id= mysys_usage_id;
found_exts.push_back((char*) triggers_file_ext);
found_exts.push_back((char*) trigname_file_ext);
- for (types= sys_table_types; *types; types++)
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
{
- if ((*types)->state == SHOW_OPTION_YES)
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (types->state == SHOW_OPTION_YES)
{
handler *file= get_new_handler((TABLE_SHARE*) 0, mem_root,
- (enum db_type) (*types)->db_type);
+ (enum db_type) types->db_type);
for (ext= file->bas_ext(); *ext; ext++)
{
while ((old_ext= it++))
@@ -2520,6 +2585,7 @@
delete file;
}
}
+ rw_unlock(&LOCK_handlers);
ext= (const char **) my_once_alloc(sizeof(char *)*
(found_exts.elements+1),
MYF(MY_WME | MY_FAE));
@@ -2550,9 +2616,9 @@
bool ha_show_status(THD *thd, enum db_type db_type, enum ha_stat_type stat)
{
- handlerton **types;
List<Item> field_list;
Protocol *protocol= thd->protocol;
+ bool result= TRUE;
field_list.push_back(new Item_empty_string("Type",10));
field_list.push_back(new Item_empty_string("Name",FN_REFLEN));
@@ -2562,25 +2628,30 @@
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
return TRUE;
- for (types= sys_table_types; *types; types++)
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
{
- if ((*types)->state == SHOW_OPTION_YES &&
- (db_type == DB_TYPE_DEFAULT || db_type == (*types)->db_type) &&
- (*types)->show_status)
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (types->state == SHOW_OPTION_YES &&
+ (db_type == DB_TYPE_DEFAULT || db_type == types->db_type) &&
+ types->show_status)
{
- if ((*types)->show_status(thd, stat_print, stat))
- return TRUE;
+ if (types->show_status(thd, stat_print, stat))
+ goto end;
}
- else if (db_type == (*types)->db_type &&
- (*types)->state != SHOW_OPTION_YES)
+ else if (db_type == types->db_type &&
+ types->state != SHOW_OPTION_YES)
{
- if (stat_print(thd, (*types)->name, "", "DISABLED"))
- return TRUE;
+ if (stat_print(thd, types->name, "", "DISABLED"))
+ goto end;
}
}
-
- send_eof(thd);
- return FALSE;
+ result= FALSE;
+end:
+ rw_unlock(&LOCK_handlers);
+ if (!result)
+ send_eof(thd);
+ return result;
}
@@ -2607,17 +2678,19 @@
my_off_t end_offset)
{
int result= 0;
- handlerton **types;
- for (types= sys_table_types; *types; types++)
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
{
- if ((*types)->state == SHOW_OPTION_YES &&
- (*types)->repl_report_sent_binlog)
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (types->state == SHOW_OPTION_YES &&
+ types->repl_report_sent_binlog)
{
- (*types)->repl_report_sent_binlog(thd,log_file_name,end_offset);
+ types->repl_report_sent_binlog(thd,log_file_name,end_offset);
result= 0;
}
}
+ rw_unlock(&LOCK_handlers);
return result;
}
@@ -2643,3 +2716,121 @@
return 0;
}
#endif /* HAVE_REPLICATION */
+
+static bool ha_global_read_lock(THD *thd)
+{
+ /* Acquire a global read lock */
+ if (thd->locked_tables)
+ {
+ THR_LOCK_DATA **lock_p= thd->locked_tables->locks;
+ THR_LOCK_DATA **end_p= lock_p + thd->locked_tables->lock_count;
+
+ for (; lock_p < end_p; lock_p++)
+ {
+ if ((*lock_p)->type == TL_WRITE)
+ {
+ my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
+ return TRUE;
+ }
+ }
+ }
+
+ if (lock_global_read_lock(thd))
+ return TRUE;
+
+ if (make_global_read_lock_block_commit(thd))
+ {
+ unlock_global_read_lock(thd);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool ha_install_storage_engine(THD *thd, handlerton *hton)
+{
+ bool result= TRUE;
+
+ if (thd && ha_global_read_lock(thd))
+ return TRUE;
+
+ rw_wrlock(&LOCK_handlers);
+ if (hash_search(&handlers, (byte*)hton->name, strlen(hton->name)))
+ {
+ if (thd)
+ my_error(ER_STORAGE_ENGINE_EXISTS, MYF(0), hton->name);
+ sql_print_error(ER(ER_STORAGE_ENGINE_EXISTS), hton->name);
+ goto end;
+ }
+
+ for (uint index= 0; index < handlers.records; index++)
+ {
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (hton->db_type != types->db_type)
+ continue;
+ if (thd)
+ my_error(ER_STORAGE_ENGINE_EXISTS, MYF(0), types->name);
+ sql_print_error("Storage Engine '%s' typecode conflicts with '%s'.",
+ hton->name, types->name);
+ goto end;
+ }
+
+ if (!hton->init || !hton->init())
+ ha_was_inited_ok(&hton);
+ else
+ {
+ hton->state= SHOW_OPTION_DISABLED;
+ if (thd)
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_STORAGE_ENGINE_INIT_FAIL,
+ ER(ER_STORAGE_ENGINE_INIT_FAIL), hton->name);
+ sql_print_error(ER(ER_STORAGE_ENGINE_INIT_FAIL), hton->name);
+ }
+
+ if (my_hash_insert(&handlers, (const byte *)hton))
+ {
+ if (thd)
+ my_error(ER_GET_ERRNO, MYF(0), ENOMEM);
+ sql_print_error("OOM installing Storage Engine '%s'.", hton->name);
+ goto end;
+ }
+
+ result= FALSE;
+
+end:
+ rw_unlock(&LOCK_handlers);
+ if (thd)
+ unlock_global_read_lock(thd);
+ return result;
+}
+
+bool ha_uninstall_storage_engine(THD *thd, handlerton *hton)
+{
+ bool result= TRUE;
+
+ if (thd && ha_global_read_lock(thd))
+ return TRUE;
+
+ rw_wrlock(&LOCK_handlers);
+ if (hash_search(&handlers, (byte*)hton->name,
+ strlen(hton->name)) != (char*) hton)
+ {
+ result= FALSE;
+ goto end;
+ }
+
+ if (hton->state == SHOW_OPTION_YES && hton->panic &&
+ hton->panic(HA_PANIC_TRY_CLOSE))
+ {
+ my_error(ER_STORAGE_ENGINE_BUSY, MYF(0), hton->name);
+ goto end;
+ }
+
+ hash_delete(&handlers, (byte*) hton);
+
+ result= FALSE;
+end:
+ rw_unlock(&LOCK_handlers);
+ if (thd)
+ unlock_global_read_lock(thd);
+ return result;
+}
--- 1.283/sql/sql_show.cc 2005-11-28 11:07:13 -08:00
+++ 1.284/sql/sql_show.cc 2005-12-01 19:24:35 -08:00
@@ -43,6 +43,8 @@
view_store_create_info(THD *thd, TABLE_LIST *table, String *buff);
static bool schema_table_store_record(THD *thd, TABLE *table);
+extern HASH handlers;
+extern rw_lock_t LOCK_handlers;
/***************************************************************************
** List all table types supported
@@ -68,27 +70,32 @@
const char *default_type_name=
ha_get_storage_engine((enum db_type)thd->variables.table_type);
- handlerton **types;
- for (types= sys_table_types; *types; types++)
+ rw_rdlock(&LOCK_handlers);
+ for (uint index= 0; index < handlers.records; index++)
{
- if (!((*types)->flags & HTON_HIDDEN))
+ handlerton *types= (handlerton *) hash_element(&handlers, index);
+ if (!(types->flags & HTON_HIDDEN))
{
protocol->prepare_for_resend();
- protocol->store((*types)->name, system_charset_info);
- const char *option_name= show_comp_option_name[(int) (*types)->state];
+ protocol->store(types->name, system_charset_info);
+ const char *option_name= show_comp_option_name[(int) types->state];
- if ((*types)->state == SHOW_OPTION_YES &&
- !my_strcasecmp(system_charset_info, default_type_name, (*types)->name))
+ if (types->state == SHOW_OPTION_YES &&
+ !my_strcasecmp(system_charset_info, default_type_name, types->name))
option_name= "DEFAULT";
protocol->store(option_name, system_charset_info);
- protocol->store((*types)->comment, system_charset_info);
- protocol->store((*types)->commit ? "YES" : "NO", system_charset_info);
- protocol->store((*types)->prepare ? "YES" : "NO", system_charset_info);
- protocol->store((*types)->savepoint_set ? "YES" : "NO", system_charset_info);
+ protocol->store(types->comment, system_charset_info);
+ protocol->store(types->commit ? "YES" : "NO", system_charset_info);
+ protocol->store(types->prepare ? "YES" : "NO", system_charset_info);
+ protocol->store(types->savepoint_set ? "YES" : "NO", system_charset_info);
if (protocol->write())
+ {
+ rw_unlock(&LOCK_handlers);
DBUG_RETURN(TRUE);
+ }
}
}
+ rw_unlock(&LOCK_handlers);
send_eof(thd);
DBUG_RETURN(FALSE);
}
--- 1.1/config/ac-macros/storage.m4 2005-11-07 07:24:45 -08:00
+++ 1.2/config/ac-macros/storage.m4 2005-12-01 19:24:34 -08:00
@@ -34,11 +34,14 @@
[mysql_cv_use_]m4_bpatsubst([$3], -, _)=[$with_]m4_bpatsubst([$3], -, _))
AH_TEMPLATE([$5], [Build $2])
if test "[$mysql_cv_use_]m4_bpatsubst([$3], -, _)" != no; then
-AC_DEFINE([$5])
-mysql_se_decls="${mysql_se_decls},$6"
-mysql_se_htons="${mysql_se_htons},&$6"
+if test "$6" != "no"
+then
+ AC_DEFINE([$5])
+ mysql_se_decls="${mysql_se_decls},$6"
+ mysql_se_htons="${mysql_se_htons},&$6"
+ mysql_se_objs="$mysql_se_objs $8"
+fi
mysql_se_dirs="$mysql_se_dirs $7"
-mysql_se_objs="$mysql_se_objs $8"
mysql_se_libs="$mysql_se_libs $9"
$10
fi
--- New file ---
+++ storage/csv/Makefile.am 05/12/01 19:24:35
# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#called from the top level Makefile
MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
MYSQLLIBdir= $(pkglibdir)
INCLUDES = -I$(top_srcdir)/include \
-I$(top_srcdir)/regex \
-I$(top_srcdir)/sql \
-I$(srcdir)
WRAPLIBS=
lib_LTLIBRARIES = libhacsv.la
libhacsv_la_SOURCES = ha_tina.cc
LDADD =
DEFS = -DMYSQL_SERVER @DEFS@
# Don't update the files from bitkeeper
%::SCCS/s.%
--- New file ---
+++ storage/example/Makefile.am 05/12/01 19:24:35
# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#called from the top level Makefile
MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
MYSQLLIBdir= $(pkglibdir)
INCLUDES = -I$(top_srcdir)/include \
-I$(top_srcdir)/regex \
-I$(top_srcdir)/sql \
-I$(srcdir)
WRAPLIBS=
lib_LTLIBRARIES = libhaexample.la
libhaexample_la_SOURCES = ha_example.cc
LDADD =
DEFS = -DMYSQL_SERVER @DEFS@
# Don't update the files from bitkeeper
%::SCCS/s.%
--- 1.56/sql/share/errmsg.txt 2005-11-23 16:56:09 -08:00
+++ 1.57/sql/share/errmsg.txt 2005-12-01 19:24:35 -08:00
@@ -5721,3 +5721,9 @@
ER_PLUGIN_IS_NOT_LOADED
eng "Plugin '%-.64s' is not loaded"
+ER_STORAGE_ENGINE_BUSY
+ eng "Storage engine '%-.64s' busy. Try using 'FLUSH TABLES' first."
+ER_STORAGE_ENGINE_INIT_FAIL
+ eng "Storage engine '%-.64s' initialization failed."
+ER_STORAGE_ENGINE_EXISTS
+ eng "Storage engine '%-.64s' already installed."
--- 1.24/sql/examples/ha_tina.cc 2005-11-23 18:08:03 -08:00
+++ 1.26/storage/csv/ha_tina.cc 2005-12-01 19:24:35 -08:00
@@ -51,18 +51,21 @@
#include "ha_tina.h"
#include <sys/mman.h>
+#include <plugin.h>
+
/* Stuff for shares */
pthread_mutex_t tina_mutex;
static HASH tina_open_tables;
static int tina_init= 0;
static handler *tina_create_handler(TABLE_SHARE *table);
+static int tina_init_func();
handlerton tina_hton= {
"CSV",
SHOW_OPTION_YES,
"CSV storage engine",
DB_TYPE_CSV_DB,
- NULL, /* One needs to be written! */
+ (bool (*)()) tina_init_func,
0, /* slot */
0, /* savepoint size. */
NULL, /* close_connection */
@@ -155,6 +158,35 @@
DBUG_RETURN(0);
}
+
+static int tina_init_func()
+{
+ if (!tina_init)
+ {
+ tina_init++;
+ VOID(pthread_mutex_init(&tina_mutex,MY_MUTEX_INIT_FAST));
+ (void) hash_init(&tina_open_tables,system_charset_info,32,0,0,
+ (hash_get_key) tina_get_key,0,0);
+ }
+ return 0;
+}
+
+static int tina_done_func()
+{
+ if (tina_init)
+ {
+ if (tina_open_tables.records)
+ {
+ return 1;
+ }
+ hash_free(&tina_open_tables);
+ pthread_mutex_destroy(&tina_mutex);
+ tina_init--;
+ }
+ return 0;
+}
+
+
/*
Simple lock controls.
*/
@@ -164,19 +196,6 @@
char *tmp_name;
uint length;
- if (!tina_init)
- {
- /* Hijack a mutex for init'ing the storage engine */
- pthread_mutex_lock(&LOCK_mysql_create_db);
- if (!tina_init)
- {
- tina_init++;
- VOID(pthread_mutex_init(&tina_mutex,MY_MUTEX_INIT_FAST));
- (void) hash_init(&tina_open_tables,system_charset_info,32,0,0,
- (hash_get_key) tina_get_key,0,0);
- }
- pthread_mutex_unlock(&LOCK_mysql_create_db);
- }
pthread_mutex_lock(&tina_mutex);
length=(uint) strlen(table_name);
if (!(share=(TINA_SHARE*) hash_search(&tina_open_tables,
@@ -262,13 +281,7 @@
int tina_end(ha_panic_function type)
{
- if (tina_init)
- {
- hash_free(&tina_open_tables);
- VOID(pthread_mutex_destroy(&tina_mutex));
- }
- tina_init= 0;
- return 0;
+ return tina_done_func();
}
/*
@@ -932,4 +945,16 @@
DBUG_RETURN(0);
}
+
+mysql_declare_plugin
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &tina_hton,
+ tina_hton.name,
+ "MySQL AB",
+ "CSV Storage Engine",
+ tina_init_func, /* Plugin Init */
+ tina_done_func /* Plugin Deinit */
+}
+mysql_declare_plugin_end;
--- 1.3/sql/sql_plugin.cc 2005-11-29 04:17:15 -08:00
+++ 1.4/sql/sql_plugin.cc 2005-12-01 19:24:35 -08:00
@@ -33,6 +33,8 @@
static rw_lock_t THR_LOCK_plugin;
static bool initialized= 0;
+extern bool ha_install_storage_engine(THD *thd, handlerton *hton);
+extern bool ha_uninstall_storage_engine(THD *thd, handlerton *hton);
static struct st_plugin_dl *plugin_dl_find(LEX_STRING *dl)
{
@@ -352,6 +354,7 @@
{
uint i;
DBUG_ENTER("plugin_call_initializer");
+redo:
for (i= 0; i < plugin_array.elements; i++)
{
struct st_plugin_int *tmp= dynamic_element(&plugin_array, i,
@@ -366,10 +369,28 @@
DBUG_PRINT("warning", ("Plugin '%s' init function returned error.",
tmp->name.str))
plugin_del(&tmp->name);
+ goto redo;
}
}
if (tmp->state == PLUGIN_IS_UNINITIALIZED)
+ {
+ switch (tmp->plugin->type)
+ {
+ case MYSQL_STORAGE_ENGINE_PLUGIN:
+ {
+ handlerton *hton= (handlerton*) tmp->plugin->info;
+ if (!hton || ha_install_storage_engine(NULL, hton))
+ {
+ plugin_del(&tmp->name);
+ goto redo;
+ }
+ break;
+ }
+ default:
+ break;
+ }
tmp->state= PLUGIN_IS_READY;
+ }
}
DBUG_VOID_RETURN;
}
@@ -547,8 +568,8 @@
"Plugin initialization function failed.");
goto err;
}
- tmp->state= PLUGIN_IS_READY;
}
+ tmp->state= PLUGIN_IS_READY;
if (! (table = open_ltable(thd, &tables, TL_WRITE)))
goto deinit;
restore_record(table, s->default_values);
@@ -560,6 +581,16 @@
table->file->print_error(error, MYF(0));
goto deinit;
}
+
+ switch (tmp->plugin->type)
+ {
+ case MYSQL_STORAGE_ENGINE_PLUGIN:
+ ha_install_storage_engine(thd, (handlerton*)tmp->plugin->info);
+ break;
+ default:
+ break;
+ }
+
rw_unlock(&THR_LOCK_plugin);
DBUG_RETURN(FALSE);
deinit:
@@ -584,6 +615,17 @@
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str);
goto err;
}
+
+ switch (plugin->plugin->type)
+ {
+ case MYSQL_STORAGE_ENGINE_PLUGIN:
+ if (ha_uninstall_storage_engine(thd, (handlerton*)plugin->plugin->info))
+ goto err;
+ break;
+ default:
+ break;
+ }
+
if (plugin->ref_count)
{
plugin->state= PLUGIN_IS_DELETED;
| Thread |
|---|
| • bk commit into 5.1 tree (acurtis:1.1995) | his.org | 2 Dec |