1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#include <drizzled/server_includes.h>
21
#include <drizzled/definitions.h>
22
#include <drizzled/base.h>
23
#include <drizzled/handler.h>
24
#include <drizzled/handlerton.h>
25
#include <drizzled/session.h>
26
#include <drizzled/error.h>
27
#include <drizzled/gettext.h>
32
While we have legacy_db_type, we have this array to
33
check for dups and to find handlerton from legacy_db_type.
34
Remove when legacy_db_type is finally gone
36
st_plugin_int *hton2plugin[MAX_HA];
38
static handlerton *installed_htons[128];
40
static const LEX_STRING sys_table_aliases[]=
42
{ C_STRING_WITH_LEN("INNOBASE") }, { C_STRING_WITH_LEN("INNODB") },
43
{ C_STRING_WITH_LEN("HEAP") }, { C_STRING_WITH_LEN("MEMORY") },
48
handlerton *ha_resolve_by_legacy_type(Session *session,
49
enum legacy_db_type db_type)
54
return ha_default_handlerton(session);
56
if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT &&
57
(plugin= ha_lock_engine(session, installed_htons[db_type])))
58
return plugin_data(plugin, handlerton*);
66
static plugin_ref ha_default_plugin(Session *session)
68
if (session->variables.table_plugin)
69
return session->variables.table_plugin;
70
return my_plugin_lock(session, &global_system_variables.table_plugin);
75
Return the default storage engine handlerton for thread
77
@param ha_default_handlerton(session)
78
@param session current thread
83
handlerton *ha_default_handlerton(Session *session)
85
plugin_ref plugin= ha_default_plugin(session);
87
handlerton *hton= plugin_data(plugin, handlerton*);
94
Return the storage engine handlerton for the supplied name
96
@param session current thread
97
@param name name of storage engine
100
pointer to storage engine plugin handle
102
plugin_ref ha_resolve_by_name(Session *session, const LEX_STRING *name)
104
const LEX_STRING *table_alias;
108
/* my_strnncoll is a macro and gcc doesn't do early expansion of macro */
109
if (session && !my_charset_utf8_general_ci.coll->strnncoll(&my_charset_utf8_general_ci,
110
(const unsigned char *)name->str, name->length,
111
(const unsigned char *)STRING_WITH_LEN("DEFAULT"), 0))
112
return ha_default_plugin(session);
114
if ((plugin= my_plugin_lock_by_name(session, name, DRIZZLE_STORAGE_ENGINE_PLUGIN)))
116
handlerton *hton= plugin_data(plugin, handlerton *);
117
if (!(hton->flags.test(HTON_BIT_NOT_USER_SELECTABLE)))
121
unlocking plugin immediately after locking is relatively low cost.
123
plugin_unlock(session, plugin);
127
We check for the historical aliases.
129
for (table_alias= sys_table_aliases; table_alias->str; table_alias+= 2)
131
if (!my_strnncoll(&my_charset_utf8_general_ci,
132
(const unsigned char *)name->str, name->length,
133
(const unsigned char *)table_alias->str,
134
table_alias->length))
136
name= table_alias + 1;
145
plugin_ref ha_lock_engine(Session *session, handlerton *hton)
149
st_plugin_int **plugin= hton2plugin + hton->slot;
151
return my_plugin_lock(session, &plugin);
158
Use other database handler if databasehandler is not compiled in.
160
handlerton *ha_checktype(Session *session, enum legacy_db_type database_type,
161
bool no_substitute, bool report_error)
163
handlerton *hton= ha_resolve_by_legacy_type(session, database_type);
164
if (ha_storage_engine_is_enabled(hton))
171
const char *engine_name= ha_resolve_storage_engine_name(hton);
172
my_error(ER_FEATURE_DISABLED,MYF(0),engine_name,engine_name);
177
return ha_default_handlerton(session);
181
handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
186
if (db_type && db_type->state == SHOW_OPTION_YES && db_type->create)
188
if ((file= db_type->create(db_type, share, alloc)))
193
Try the default table type
194
Here the call to current_session() is ok as we call this function a lot of
195
times but we enter this branch very seldom.
197
return(get_new_handler(share, alloc, ha_default_handlerton(current_session)));
201
int ha_finalize_handlerton(st_plugin_int *plugin)
203
handlerton *hton= (handlerton *)plugin->data;
208
case SHOW_OPTION_DISABLED:
210
case SHOW_OPTION_YES:
211
if (installed_htons[hton->db_type] == hton)
212
installed_htons[hton->db_type]= NULL;
216
if (hton && plugin->plugin->deinit)
217
(void)plugin->plugin->deinit(hton);
219
free((unsigned char*)hton);
225
int ha_initialize_handlerton(st_plugin_int *plugin)
229
hton= (handlerton *)malloc(sizeof(handlerton));
230
memset(hton, 0, sizeof(handlerton));
232
/* Historical Requirement */
233
plugin->data= hton; // shortcut for the future
234
if (plugin->plugin->init)
236
if (plugin->plugin->init(hton))
238
sql_print_error(_("Plugin '%s' init function returned error."),
244
hton->name= plugin->name.str;
247
the switch below and hton->state should be removed when
248
command-line options for plugins will be implemented
250
switch (hton->state) {
253
case SHOW_OPTION_YES:
256
/* now check the db_type for conflict */
257
if (hton->db_type <= DB_TYPE_UNKNOWN ||
258
hton->db_type >= DB_TYPE_DEFAULT ||
259
installed_htons[hton->db_type])
261
int idx= (int) DB_TYPE_FIRST_DYNAMIC;
263
while (idx < (int) DB_TYPE_DEFAULT && installed_htons[idx])
266
if (idx == (int) DB_TYPE_DEFAULT)
268
sql_print_warning(_("Too many storage engines!"));
271
if (hton->db_type != DB_TYPE_UNKNOWN)
272
sql_print_warning(_("Storage engine '%s' has conflicting typecode. "
273
"Assigning value %d."), plugin->plugin->name, idx);
274
hton->db_type= (enum legacy_db_type) idx;
276
installed_htons[hton->db_type]= hton;
277
tmp= hton->savepoint_offset;
278
hton->savepoint_offset= savepoint_alloc_size;
279
savepoint_alloc_size+= tmp;
280
hton->slot= total_ha++;
281
hton2plugin[hton->slot]=plugin;
288
hton->state= SHOW_OPTION_DISABLED;
293
This is entirely for legacy. We will create a new "disk based" hton and a
294
"memory" hton which will be configurable longterm. We should be able to
295
remove partition and myisammrg.
297
if (strcmp(plugin->plugin->name, "MEMORY") == 0)
300
if (strcmp(plugin->plugin->name, "MyISAM") == 0)
308
enum legacy_db_type ha_legacy_type(const handlerton *db_type)
310
return (db_type == NULL) ? DB_TYPE_UNKNOWN : db_type->db_type;
313
const char *ha_resolve_storage_engine_name(const handlerton *db_type)
315
return db_type == NULL ? "UNKNOWN" : hton2plugin[db_type->slot]->name.str;
318
bool ha_check_storage_engine_flag(const handlerton *db_type, const hton_flag_bits flag)
320
return db_type == NULL ? false : db_type->flags.test(static_cast<size_t>(flag));
323
bool ha_storage_engine_is_enabled(const handlerton *db_type)
325
return (db_type && db_type->create) ?
326
(db_type->state == SHOW_OPTION_YES) : false;
329
LEX_STRING *ha_storage_engine_name(const handlerton *hton)
331
return &hton2plugin[hton->slot]->name;