summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
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;