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/sql_class.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 & HTON_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 *)my_malloc(sizeof(handlerton),
230
MYF(MY_WME | MY_ZEROFILL));
232
FIXME: the MY_ZEROFILL flag above doesn't zero all the bytes.
234
This was detected after adding get_backup_engine member to handlerton
235
structure. Apparently get_backup_engine was not NULL even though it was
238
memset(hton, 0, sizeof(hton));
239
/* Historical Requirement */
240
plugin->data= hton; // shortcut for the future
241
if (plugin->plugin->init)
243
if (plugin->plugin->init(hton))
245
sql_print_error(_("Plugin '%s' init function returned error."),
252
the switch below and hton->state should be removed when
253
command-line options for plugins will be implemented
255
switch (hton->state) {
258
case SHOW_OPTION_YES:
261
/* now check the db_type for conflict */
262
if (hton->db_type <= DB_TYPE_UNKNOWN ||
263
hton->db_type >= DB_TYPE_DEFAULT ||
264
installed_htons[hton->db_type])
266
int idx= (int) DB_TYPE_FIRST_DYNAMIC;
268
while (idx < (int) DB_TYPE_DEFAULT && installed_htons[idx])
271
if (idx == (int) DB_TYPE_DEFAULT)
273
sql_print_warning(_("Too many storage engines!"));
276
if (hton->db_type != DB_TYPE_UNKNOWN)
277
sql_print_warning(_("Storage engine '%s' has conflicting typecode. "
278
"Assigning value %d."), plugin->plugin->name, idx);
279
hton->db_type= (enum legacy_db_type) idx;
281
installed_htons[hton->db_type]= hton;
282
tmp= hton->savepoint_offset;
283
hton->savepoint_offset= savepoint_alloc_size;
284
savepoint_alloc_size+= tmp;
285
hton->slot= total_ha++;
286
hton2plugin[hton->slot]=plugin;
293
hton->state= SHOW_OPTION_DISABLED;
298
This is entirely for legacy. We will create a new "disk based" hton and a
299
"memory" hton which will be configurable longterm. We should be able to
300
remove partition and myisammrg.
302
if (strcmp(plugin->plugin->name, "MEMORY") == 0)
305
if (strcmp(plugin->plugin->name, "MyISAM") == 0)
313
enum legacy_db_type ha_legacy_type(const handlerton *db_type)
315
return (db_type == NULL) ? DB_TYPE_UNKNOWN : db_type->db_type;
318
const char *ha_resolve_storage_engine_name(const handlerton *db_type)
320
return db_type == NULL ? "UNKNOWN" : hton2plugin[db_type->slot]->name.str;
323
bool ha_check_storage_engine_flag(const handlerton *db_type, uint32_t flag)
325
return db_type == NULL ? false : test(db_type->flags & flag);
328
bool ha_storage_engine_is_enabled(const handlerton *db_type)
330
return (db_type && db_type->create) ?
331
(db_type->state == SHOW_OPTION_YES) : false;
334
LEX_STRING *ha_storage_engine_name(const handlerton *hton)
336
return &hton2plugin[hton->slot]->name;