~drizzle-trunk/drizzle/development

575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2008 Sun Microsystems
5
 *
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.
9
 *
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.
14
 *
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
18
 */
19
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>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
25
#include <drizzled/session.h>
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
26
#include <drizzled/error.h>
27
#include <drizzled/gettext.h>
28
29
#include CSTDINT_H
30
31
/*
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
35
*/
36
st_plugin_int *hton2plugin[MAX_HA];
37
38
static handlerton *installed_htons[128];
39
40
static const LEX_STRING sys_table_aliases[]=
41
{
42
  { C_STRING_WITH_LEN("INNOBASE") },  { C_STRING_WITH_LEN("INNODB") },
43
  { C_STRING_WITH_LEN("HEAP") },      { C_STRING_WITH_LEN("MEMORY") },
44
  {NULL, 0}
45
};
46
47
48
handlerton *ha_resolve_by_legacy_type(Session *session,
49
                                      enum legacy_db_type db_type)
50
{
51
  plugin_ref plugin;
52
  switch (db_type) {
53
  case DB_TYPE_DEFAULT:
54
    return ha_default_handlerton(session);
55
  default:
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*);
59
    /* fall through */
60
  case DB_TYPE_UNKNOWN:
61
    return NULL;
62
  }
63
}
64
65
66
static plugin_ref ha_default_plugin(Session *session)
67
{
68
  if (session->variables.table_plugin)
69
    return session->variables.table_plugin;
70
  return my_plugin_lock(session, &global_system_variables.table_plugin);
71
}
72
73
74
/**
75
  Return the default storage engine handlerton for thread
76
77
  @param ha_default_handlerton(session)
78
  @param session         current thread
79
80
  @return
81
    pointer to handlerton
82
*/
83
handlerton *ha_default_handlerton(Session *session)
84
{
85
  plugin_ref plugin= ha_default_plugin(session);
86
  assert(plugin);
87
  handlerton *hton= plugin_data(plugin, handlerton*);
88
  assert(hton);
89
  return hton;
90
}
91
92
93
/**
94
  Return the storage engine handlerton for the supplied name
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
95
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
96
  @param session         current thread
97
  @param name        name of storage engine
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
98
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
99
  @return
100
    pointer to storage engine plugin handle
101
*/
102
plugin_ref ha_resolve_by_name(Session *session, const LEX_STRING *name)
103
{
104
  const LEX_STRING *table_alias;
105
  plugin_ref plugin;
106
107
redo:
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);
113
114
  if ((plugin= my_plugin_lock_by_name(session, name, DRIZZLE_STORAGE_ENGINE_PLUGIN)))
115
  {
116
    handlerton *hton= plugin_data(plugin, handlerton *);
631.1.1 by Yoshinori Sano
Replace "uint_32 flags" member of handlerton with std::bitset. Add some TODOs as comments for this change.
117
    if (!(hton->flags.test(HTON_BIT_NOT_USER_SELECTABLE)))
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
118
      return plugin;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
119
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
120
    /*
121
      unlocking plugin immediately after locking is relatively low cost.
122
    */
123
    plugin_unlock(session, plugin);
124
  }
125
126
  /*
127
    We check for the historical aliases.
128
  */
129
  for (table_alias= sys_table_aliases; table_alias->str; table_alias+= 2)
130
  {
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))
135
    {
136
      name= table_alias + 1;
137
      goto redo;
138
    }
139
  }
140
141
  return NULL;
142
}
143
144
145
plugin_ref ha_lock_engine(Session *session, handlerton *hton)
146
{
147
  if (hton)
148
  {
149
    st_plugin_int **plugin= hton2plugin + hton->slot;
150
151
    return my_plugin_lock(session, &plugin);
152
  }
153
  return NULL;
154
}
155
156
157
/**
158
  Use other database handler if databasehandler is not compiled in.
159
*/
160
handlerton *ha_checktype(Session *session, enum legacy_db_type database_type,
161
                          bool no_substitute, bool report_error)
162
{
163
  handlerton *hton= ha_resolve_by_legacy_type(session, database_type);
164
  if (ha_storage_engine_is_enabled(hton))
165
    return hton;
166
167
  if (no_substitute)
168
  {
169
    if (report_error)
170
    {
171
      const char *engine_name= ha_resolve_storage_engine_name(hton);
172
      my_error(ER_FEATURE_DISABLED,MYF(0),engine_name,engine_name);
173
    }
174
    return NULL;
175
  }
176
177
  return ha_default_handlerton(session);
178
} /* ha_checktype */
179
180
181
handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
182
                         handlerton *db_type)
183
{
184
  handler *file;
185
186
  if (db_type && db_type->state == SHOW_OPTION_YES && db_type->create)
187
  {
188
    if ((file= db_type->create(db_type, share, alloc)))
189
      file->init();
190
    return(file);
191
  }
192
  /*
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.
196
  */
197
  return(get_new_handler(share, alloc, ha_default_handlerton(current_session)));
198
}
199
200
201
int ha_finalize_handlerton(st_plugin_int *plugin)
202
{
203
  handlerton *hton= (handlerton *)plugin->data;
204
205
  switch (hton->state)
206
  {
207
  case SHOW_OPTION_NO:
208
  case SHOW_OPTION_DISABLED:
209
    break;
210
  case SHOW_OPTION_YES:
211
    if (installed_htons[hton->db_type] == hton)
212
      installed_htons[hton->db_type]= NULL;
213
    break;
214
  };
215
216
  if (hton && plugin->plugin->deinit)
217
    (void)plugin->plugin->deinit(hton);
218
219
  free((unsigned char*)hton);
220
221
  return(0);
222
}
223
224
225
int ha_initialize_handlerton(st_plugin_int *plugin)
226
{
227
  handlerton *hton;
228
641.3.8 by Monty Taylor
Removed my_malloc from drizzled.
229
  hton= (handlerton *)malloc(sizeof(handlerton));
230
  memset(hton, 0, sizeof(handlerton));
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
231
232
  /* Historical Requirement */
233
  plugin->data= hton; // shortcut for the future
234
  if (plugin->plugin->init)
235
  {
236
    if (plugin->plugin->init(hton))
237
    {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
238
      errmsg_printf(ERRMSG_LVL_ERROR, _("Plugin '%s' init function returned error."),
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
239
                      plugin->name.str);
240
      goto err;
241
    }
242
  }
243
584.2.5 by Stewart Smith
store a protobuf tabledefinition along with FRM
244
  hton->name= plugin->name.str;
245
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
246
  /*
247
    the switch below and hton->state should be removed when
248
    command-line options for plugins will be implemented
249
  */
250
  switch (hton->state) {
251
  case SHOW_OPTION_NO:
252
    break;
253
  case SHOW_OPTION_YES:
254
    {
255
      uint32_t tmp;
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])
260
      {
261
        int idx= (int) DB_TYPE_FIRST_DYNAMIC;
262
263
        while (idx < (int) DB_TYPE_DEFAULT && installed_htons[idx])
264
          idx++;
265
266
        if (idx == (int) DB_TYPE_DEFAULT)
267
        {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
268
          errmsg_printf(ERRMSG_LVL_WARN, _("Too many storage engines!"));
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
269
          return(1);
270
        }
271
        if (hton->db_type != DB_TYPE_UNKNOWN)
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
272
          errmsg_printf(ERRMSG_LVL_WARN,
273
                        _("Storage engine '%s' has conflicting typecode. Assigning value %d."),
274
                        plugin->plugin->name, idx);
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
275
        hton->db_type= (enum legacy_db_type) idx;
276
      }
277
      installed_htons[hton->db_type]= hton;
278
      tmp= hton->savepoint_offset;
279
      hton->savepoint_offset= savepoint_alloc_size;
280
      savepoint_alloc_size+= tmp;
281
      hton->slot= total_ha++;
282
      hton2plugin[hton->slot]=plugin;
283
      if (hton->prepare)
284
        total_ha_2pc++;
285
      break;
286
    }
287
    /* fall through */
288
  default:
289
    hton->state= SHOW_OPTION_DISABLED;
290
    break;
291
  }
292
293
  /*
294
    This is entirely for legacy. We will create a new "disk based" hton and a
295
    "memory" hton which will be configurable longterm. We should be able to
296
    remove partition and myisammrg.
297
  */
298
  if (strcmp(plugin->plugin->name, "MEMORY") == 0)
299
    heap_hton= hton;
300
301
  if (strcmp(plugin->plugin->name, "MyISAM") == 0)
302
    myisam_hton= hton;
303
810 by Brian Aker
Fix for making sure I_S has good information about which plugins are
304
  plugin->state= PLUGIN_IS_READY;
305
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
306
  return(0);
307
err:
308
  return(1);
309
}
310
311
enum legacy_db_type ha_legacy_type(const handlerton *db_type)
312
{
313
  return (db_type == NULL) ? DB_TYPE_UNKNOWN : db_type->db_type;
314
}
315
316
const char *ha_resolve_storage_engine_name(const handlerton *db_type)
317
{
318
  return db_type == NULL ? "UNKNOWN" : hton2plugin[db_type->slot]->name.str;
319
}
320
631.1.2 by Yoshinori Sano
Move hton_flag_bits and HTON_* to handlerton.h. Remove TODOs previously added.
321
bool ha_check_storage_engine_flag(const handlerton *db_type, const hton_flag_bits flag)
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
322
{
631.1.2 by Yoshinori Sano
Move hton_flag_bits and HTON_* to handlerton.h. Remove TODOs previously added.
323
  return db_type == NULL ? false : db_type->flags.test(static_cast<size_t>(flag));
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
324
}
325
326
bool ha_storage_engine_is_enabled(const handlerton *db_type)
327
{
328
  return (db_type && db_type->create) ?
329
         (db_type->state == SHOW_OPTION_YES) : false;
330
}
331
332
LEX_STRING *ha_storage_engine_name(const handlerton *hton)
333
{
334
  return &hton2plugin[hton->slot]->name;
335
}