diff options
author | unknown <antony@ppcg5.local> | 2007-03-02 08:43:45 -0800 |
---|---|---|
committer | unknown <antony@ppcg5.local> | 2007-03-02 08:43:45 -0800 |
commit | aac0c0d90ac65fdb8d6e60130db2c61a1bea0121 (patch) | |
tree | 23fe49e9ab83f6badb4e173587f9e194490a3859 /sql/handler.cc | |
parent | 7c638e0be47932877a1de1e593a91d391cba8651 (diff) | |
download | mariadb-git-aac0c0d90ac65fdb8d6e60130db2c61a1bea0121.tar.gz |
WL#2936
"Server Variables for Plugins"
Implement support for plugins to declare server variables.
Demonstrate functionality by removing InnoDB specific code from sql/*
New feature for HASH - HASH_UNIQUE flag
New feature for DYNAMIC_ARRAY - initializer accepts preallocated ptr.
Completed support for plugin reference counting.
include/hash.h:
New flag for HASH
HASH_UNIQUE
include/my_getopt.h:
New data types for options: ENUM and SET.
Use typelib to enumerate possible values.
New flag variable:
my_getopt_skip_unknown
include/my_sys.h:
change to DYNAMIC_ARRAY init functions to support pre-allocated buffers
include/mysql.h:
relocate inclusion of typelib due to longlong requirement
include/mysql/plugin.h:
wl2936
New declarations for plugin server variable support.
New functions for use by plugins
include/mysys_err.h:
new my_getopt return value: EXIT_ARGUMENT_INVALID
include/typelib.h:
new typelib function: find_typeset(), returns an int which is a SET of
the elements in the typelib
mysql-test/r/im_utils.result:
change to more specific command line settings
--skip-innodb => --skip-plugin-innodb
etc.
mysql-test/r/log_tables.result:
set default storage engine to MEMORY so that test will succeed even
when some of the other named storage engines are not present
mysql-test/r/ndb_dd_basic.result:
change in error message
mysql-test/r/partition_innodb.result:
change in results
mysql-test/r/ps_1general.result:
bdb doesn't exist, use myisam for a non-transactional engine
mysql-test/r/variables.result:
information schema doesn't sort row results for server variables.
mysql-test/t/log_tables.test:
set default storage engine to MEMORY so that test will succeed even
when some of the other named storage engines are not present
mysql-test/t/ndb_dd_basic.test:
ALTER LOGFILE GROUP no longer silently fail here
mysql-test/t/partition_innodb.test:
ALTER TABLE no longer silently fails for unknown storage engine
mysql-test/t/ps_1general.test:
remove unneccessary parts
use myisam as it is an always present non-transactional engine
mysql-test/t/variables.test:
information schema doesn't sort row results for server variables.
mysql-test/t/warnings_engine_disabled-master.opt:
use the new style command line option
mysys/array.c:
change to DYNAMIC_ARRAY init functions to support pre-allocated buffers
mysys/hash.c:
New flag for HASH
HASH_UNIQUE
Implement HASH_UNIQUE functionality by performing a hash_search
mysys/my_getopt.c:
New data types for options: ENUM and SET.
Use typelib to enumerate possible values.
New flag variable:
my_getopt_skip_unknown
mysys/typelib.c:
new typelib function: find_typeset(), returns an int which is a SET of
the elements in the typelib
sql/ha_ndbcluster.cc:
use ha_statistic_increment() method instead of
statistic_increment() function
ha_ndbcluster variable has gone away.
sql/ha_partition.cc:
fix for reference counting
sql/ha_partition.h:
fix for reference counting
sql/handler.cc:
fixes for reference counting
sql/handler.h:
fixes for reference counting
some new methods to aid storage engine writers
sql/item_func.cc:
find_sys_var() function now requires thd
sql/item_sum.cc:
fixes for ref counting
sql/mysql_priv.h:
remove unneccessary globals.
new lock: LOCK_system_variables_hash
sql/mysqld.cc:
Remove InnoBase specific code.
Support plugin command line processing.
sql/set_var.cc:
Remove InnoBase specific declarations
Remove redundant declarations
changes to permit new variables at run time
changes for ref counting
sql/set_var.h:
changes to permit new variables at run time
changes for ref counting
sql/sql_base.cc:
changes for ref counting
sql/sql_cache.cc:
mark code as needing work in the future
sql/sql_class.cc:
new functions to aid plugin authors
initialize variables for dynamic plugin variables
sql/sql_class.h:
remove InnoBase specific declarations
New declarations for plugin variables.
sql/sql_connect.cc:
initialization and cleanup of plugin variables
sql/sql_delete.cc:
change for ref counting
sql/sql_insert.cc:
change for ref counting
sql/sql_lex.cc:
changes for ref counting and plugin variables
sql/sql_lex.h:
add properties for plugin ref counting,
add to distructor to clean up
sql/sql_partition.cc:
changes for ref counting
sql/sql_plugin.cc:
WL2936
Plugin Variables
New methods and code to support server variables for plugins.
New code to complete plugin reference counting
Debug code adds further indirection so that malloc debugging can be
used to aid finding plugin ref count leaks
sql/sql_plugin.h:
WL2936
Plugin Variables
New methods and code to support server variables for plugins.
New code to complete plugin reference counting
Debug code adds further indirection so that malloc debugging can be
used to aid finding plugin ref count leaks
sql/sql_repl.cc:
replication system variables moved here from set_var.cc
sql/sql_repl.h:
new function to initialise replication server variables
sql/sql_select.cc:
changes for ref counting
sql/sql_show.cc:
changes for ref counting
sql/sql_table.cc:
changes for ref counting
sql/sql_tablespace.cc:
use supplied functions instead of digging into data structures manually
sql/sql_yacc.yy:
changes for ref counting
find_sys_var() now requires thd parameter
changes on reporting errors to keep user-visible behaviour the same.
sql/structs.h:
changes for ref counting
sql/table.cc:
changes for ref counting
sql/table.h:
changes for ref counting
storage/federated/ha_federated.cc:
use ha_statistic_increment() method instead of statistic_increment()
function
storage/heap/ha_heap.cc:
use ha_statistic_increment() method instead of statistic_increment()
function
storage/innobase/handler/ha_innodb.cc:
use ha_statistic_increment() method instead of statistic_increment()
function
WL2936
Move InnoBase specific code out of mysqld.cc and into here
Declare all required server variables for InnoBase
storage/innobase/include/trx0trx.h:
store a bit more state so that InnoBase does not have to dig into
mysqld internal data structures.
storage/myisam/ha_myisam.cc:
use ha_statistic_increment() method instead of statistic_increment()
function
storage/myisammrg/ha_myisammrg.cc:
use ha_statistic_increment() method instead of statistic_increment()
function
Diffstat (limited to 'sql/handler.cc')
-rw-r--r-- | sql/handler.cc | 168 |
1 files changed, 102 insertions, 66 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index 2244aaa5311..bb7c39be262 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -77,6 +77,15 @@ static TYPELIB known_extensions= {0,"known_exts", NULL, NULL}; uint known_extensions_id= 0; + +static plugin_ref ha_default_plugin(THD *thd) +{ + if (thd->variables.table_plugin) + return thd->variables.table_plugin; + return my_plugin_lock(thd, &global_system_variables.table_plugin); +} + + /** @brief Return the default storage engine handlerton for thread @@ -89,10 +98,11 @@ uint known_extensions_id= 0; */ handlerton *ha_default_handlerton(THD *thd) { - return (thd->variables.table_type != NULL) ? - thd->variables.table_type : - (global_system_variables.table_type != NULL ? - global_system_variables.table_type : myisam_hton); + plugin_ref plugin= ha_default_plugin(thd); + DBUG_ASSERT(plugin); + handlerton *hton= plugin_data(plugin, handlerton*); + DBUG_ASSERT(hton); + return hton; } @@ -105,26 +115,30 @@ handlerton *ha_default_handlerton(THD *thd) name name of storage engine RETURN - pointer to handlerton + pointer to storage engine plugin handle */ -handlerton *ha_resolve_by_name(THD *thd, const LEX_STRING *name) +plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name) { const LEX_STRING *table_alias; - st_plugin_int *plugin; + plugin_ref plugin; redo: /* my_strnncoll is a macro and gcc doesn't do early expansion of macro */ if (thd && !my_charset_latin1.coll->strnncoll(&my_charset_latin1, (const uchar *)name->str, name->length, (const uchar *)STRING_WITH_LEN("DEFAULT"), 0)) - return ha_default_handlerton(thd); + return ha_default_plugin(thd); - if ((plugin= plugin_lock(name, MYSQL_STORAGE_ENGINE_PLUGIN))) + if ((plugin= my_plugin_lock_by_name(thd, name, MYSQL_STORAGE_ENGINE_PLUGIN))) { - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); if (!(hton->flags & HTON_NOT_USER_SELECTABLE)) - return hton; - plugin_unlock(plugin); + return plugin; + + /* + unlocking plugin immediately after locking is relatively low cost. + */ + plugin_unlock(thd, plugin); } /* @@ -145,19 +159,19 @@ redo: } -const char *ha_get_storage_engine(enum legacy_db_type db_type) +plugin_ref ha_lock_engine(THD *thd, handlerton *hton) { - switch (db_type) { - case DB_TYPE_DEFAULT: - return "DEFAULT"; - default: - if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT && - installed_htons[db_type]) - return hton2plugin[installed_htons[db_type]->slot]->name.str; - /* fall through */ - case DB_TYPE_UNKNOWN: - return "UNKNOWN"; + if (hton) + { + st_plugin_int **plugin= hton2plugin + hton->slot; + +#ifdef DBUG_OFF; + return my_plugin_lock(thd, plugin); +#else + return my_plugin_lock(thd, &plugin); +#endif } + return NULL; } @@ -172,14 +186,16 @@ static handler *create_default(TABLE_SHARE *table, MEM_ROOT *mem_root) handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type) { + plugin_ref plugin; switch (db_type) { case DB_TYPE_DEFAULT: return ha_default_handlerton(thd); - case DB_TYPE_UNKNOWN: - return NULL; default: - if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT) - return installed_htons[db_type]; + if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT && + (plugin= ha_lock_engine(thd, installed_htons[db_type]))) + return plugin_data(plugin, handlerton*); + /* fall through */ + case DB_TYPE_UNKNOWN: return NULL; } } @@ -199,7 +215,7 @@ handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type, { if (report_error) { - const char *engine_name= ha_get_storage_engine(database_type); + const char *engine_name= ha_resolve_storage_engine_name(hton); my_error(ER_FEATURE_DISABLED,MYF(0),engine_name,engine_name); } return NULL; @@ -238,8 +254,7 @@ handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc, Here the call to current_thd() is ok as we call this function a lot of times but we enter this branch very seldom. */ - DBUG_RETURN(get_new_handler(share, alloc, - current_thd->variables.table_type)); + DBUG_RETURN(get_new_handler(share, alloc, ha_default_handlerton(current_thd))); } @@ -522,10 +537,10 @@ int ha_end() DBUG_RETURN(error); } -static my_bool dropdb_handlerton(THD *unused1, st_plugin_int *plugin, +static my_bool dropdb_handlerton(THD *unused1, plugin_ref plugin, void *path) { - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); if (hton->state == SHOW_OPTION_YES && hton->drop_database) hton->drop_database(hton, (char *)path); return FALSE; @@ -538,10 +553,10 @@ void ha_drop_database(char* path) } -static my_bool closecon_handlerton(THD *thd, st_plugin_int *plugin, +static my_bool closecon_handlerton(THD *thd, plugin_ref plugin, void *unused) { - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); /* there's no need to rollback here as all transactions must be rolled back already @@ -638,7 +653,7 @@ int ha_prepare(THD *thd) { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), - hton2plugin[(*ht)->slot]->name.str); + ha_resolve_storage_engine_name(*ht)); } } } @@ -886,10 +901,10 @@ struct xahton_st { int result; }; -static my_bool xacommit_handlerton(THD *unused1, st_plugin_int *plugin, +static my_bool xacommit_handlerton(THD *unused1, plugin_ref plugin, void *arg) { - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); if (hton->state == SHOW_OPTION_YES && hton->recover) { hton->commit_by_xid(hton, ((struct xahton_st *)arg)->xid); @@ -898,10 +913,10 @@ static my_bool xacommit_handlerton(THD *unused1, st_plugin_int *plugin, return FALSE; } -static my_bool xarollback_handlerton(THD *unused1, st_plugin_int *plugin, +static my_bool xarollback_handlerton(THD *unused1, plugin_ref plugin, void *arg) { - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); if (hton->state == SHOW_OPTION_YES && hton->recover) { hton->rollback_by_xid(hton, ((struct xahton_st *)arg)->xid); @@ -1004,10 +1019,10 @@ struct xarecover_st bool dry_run; }; -static my_bool xarecover_handlerton(THD *unused, st_plugin_int *plugin, +static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin, void *arg) { - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); struct xarecover_st *info= (struct xarecover_st *) arg; int got; @@ -1016,7 +1031,7 @@ static my_bool xarecover_handlerton(THD *unused, st_plugin_int *plugin, while ((got= hton->recover(hton, info->list, info->len)) > 0 ) { sql_print_information("Found %d prepared transaction(s) in %s", - got, hton2plugin[hton->slot]->name.str); + got, ha_resolve_storage_engine_name(hton)); for (int i=0; i < got; i ++) { my_xid x=info->list[i].get_my_xid(); @@ -1192,10 +1207,10 @@ bool mysql_xa_recover(THD *thd) thd: the thread handle of the current connection return value: always 0 */ -static my_bool release_temporary_latches(THD *thd, st_plugin_int *plugin, +static my_bool release_temporary_latches(THD *thd, plugin_ref plugin, void *unused) { - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); if (hton->state == SHOW_OPTION_YES && hton->release_temporary_latches) hton->release_temporary_latches(hton, thd); @@ -1318,10 +1333,10 @@ int ha_release_savepoint(THD *thd, SAVEPOINT *sv) } -static my_bool snapshot_handlerton(THD *thd, st_plugin_int *plugin, +static my_bool snapshot_handlerton(THD *thd, plugin_ref plugin, void *arg) { - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); if (hton->state == SHOW_OPTION_YES && hton->start_consistent_snapshot) { @@ -1349,10 +1364,10 @@ int ha_start_consistent_snapshot(THD *thd) } -static my_bool flush_handlerton(THD *thd, st_plugin_int *plugin, +static my_bool flush_handlerton(THD *thd, plugin_ref plugin, void *arg) { - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); if (hton->state == SHOW_OPTION_YES && hton->flush_logs && hton->flush_logs(hton)) return TRUE; @@ -1397,7 +1412,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, /* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */ if (table_type == NULL || - ! (file=get_new_handler(&dummy_share, thd->mem_root, table_type))) + ! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type))) DBUG_RETURN(ENOENT); if (lower_case_table_names == 2 && !(file->ha_table_flags() & HA_FILE_BASED)) @@ -1438,6 +1453,8 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, dummy_share.table_name.length= strlen(alias); dummy_table.alias= alias; + file->table_share= &dummy_share; + file->table= &dummy_table; file->print_error(error, 0); strmake(new_error, thd->net.last_error, sizeof(buff)-1); @@ -1458,7 +1475,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, ****************************************************************************/ handler *handler::clone(MEM_ROOT *mem_root) { - handler *new_handler= get_new_handler(table->s, mem_root, table->s->db_type); + handler *new_handler= get_new_handler(table->s, mem_root, table->s->db_type()); if (new_handler && !new_handler->ha_open(table, table->s->normalized_path.str, table->db_stat, @@ -1474,6 +1491,26 @@ void handler::ha_statistic_increment(ulong SSV::*offset) const statistic_increment(table->in_use->status_var.*offset, &LOCK_status); } +enum enum_tx_isolation handler::ha_tx_isolation(void) const +{ + return (enum_tx_isolation) ha_thd()->variables.tx_isolation; +} + +uint handler::ha_sql_command(void) const +{ + return (uint) ha_thd()->lex->sql_command; +} + +void **handler::ha_data(void) const +{ + return (void **) ha_thd()->ha_data + ht->slot; +} + +THD *handler::ha_thd(void) const +{ + return (table && table->in_use) ? table->in_use : current_thd; +} + bool handler::check_if_log_table_locking_is_allowed(uint sql_command, ulong type, TABLE *table) @@ -1567,8 +1604,7 @@ int handler::read_first_row(byte * buf, uint primary_key) register int error; DBUG_ENTER("handler::read_first_row"); - statistic_increment(table->in_use->status_var.ha_read_first_count, - &LOCK_status); + ha_statistic_increment(&SSV::ha_read_first_count); /* If there is very few deleted rows in the table, find the first row by @@ -2785,11 +2821,11 @@ struct st_discover_args uint* frmlen; }; -static my_bool discover_handlerton(THD *thd, st_plugin_int *plugin, +static my_bool discover_handlerton(THD *thd, plugin_ref plugin, void *arg) { st_discover_args *vargs= (st_discover_args *)arg; - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); if (hton->state == SHOW_OPTION_YES && hton->discover && (!(hton->discover(hton, thd, vargs->db, vargs->name, vargs->frmblob, @@ -2834,11 +2870,11 @@ struct st_find_files_args List<char> *files; }; -static my_bool find_files_handlerton(THD *thd, st_plugin_int *plugin, +static my_bool find_files_handlerton(THD *thd, plugin_ref plugin, void *arg) { st_find_files_args *vargs= (st_find_files_args *)arg; - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); if (hton->state == SHOW_OPTION_YES && hton->find_files) @@ -2881,11 +2917,11 @@ struct st_table_exists_in_engine_args const char *name; }; -static my_bool table_exists_in_engine_handlerton(THD *thd, st_plugin_int *plugin, +static my_bool table_exists_in_engine_handlerton(THD *thd, plugin_ref plugin, void *arg) { st_table_exists_in_engine_args *vargs= (st_table_exists_in_engine_args *)arg; - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); if (hton->state == SHOW_OPTION_YES && hton->table_exists_in_engine) if ((hton->table_exists_in_engine(hton, thd, vargs->db, vargs->name)) == 1) @@ -2929,10 +2965,10 @@ struct binlog_func_st /** @brief Listing handlertons first to avoid recursive calls and deadlock */ -static my_bool binlog_func_list(THD *thd, st_plugin_int *plugin, void *arg) +static my_bool binlog_func_list(THD *thd, plugin_ref plugin, void *arg) { hton_list_st *hton_list= (hton_list_st *)arg; - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); if (hton->state == SHOW_OPTION_YES && hton->binlog_func) { uint sz= hton_list->sz; @@ -3019,10 +3055,10 @@ static my_bool binlog_log_query_handlerton2(THD *thd, } static my_bool binlog_log_query_handlerton(THD *thd, - st_plugin_int *plugin, + plugin_ref plugin, void *args) { - return binlog_log_query_handlerton2(thd, (handlerton *)plugin->data, args); + return binlog_log_query_handlerton2(thd, plugin_data(plugin, handlerton *), args); } void ha_binlog_log_query(THD *thd, handlerton *hton, @@ -3310,11 +3346,11 @@ int handler::index_read_idx(byte * buf, uint index, const byte * key, RETURN VALUE pointer pointer to TYPELIB structure */ -static my_bool exts_handlerton(THD *unused, st_plugin_int *plugin, +static my_bool exts_handlerton(THD *unused, plugin_ref plugin, void *arg) { List<char> *found_exts= (List<char> *) arg; - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); handler *file; if (hton->state == SHOW_OPTION_YES && hton->create && (file= hton->create(hton, (TABLE_SHARE*) 0, current_thd->mem_root))) @@ -3385,11 +3421,11 @@ static bool stat_print(THD *thd, const char *type, uint type_len, } -static my_bool showstat_handlerton(THD *thd, st_plugin_int *plugin, +static my_bool showstat_handlerton(THD *thd, plugin_ref plugin, void *arg) { enum ha_stat_type stat= *(enum ha_stat_type *) arg; - handlerton *hton= (handlerton *)plugin->data; + handlerton *hton= plugin_data(plugin, handlerton *); if (hton->state == SHOW_OPTION_YES && hton->show_status && hton->show_status(hton, thd, stat_print, stat)) return TRUE; |