summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
authorunknown <antony@ppcg5.local>2007-03-02 08:43:45 -0800
committerunknown <antony@ppcg5.local>2007-03-02 08:43:45 -0800
commitaac0c0d90ac65fdb8d6e60130db2c61a1bea0121 (patch)
tree23fe49e9ab83f6badb4e173587f9e194490a3859 /sql/handler.cc
parent7c638e0be47932877a1de1e593a91d391cba8651 (diff)
downloadmariadb-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.cc168
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;