21
21
#define DRIZZLED_PLUGIN_STORAGE_ENGINE_H
24
#include <drizzled/cached_directory.h>
25
24
#include <drizzled/definitions.h>
26
#include <drizzled/error_t.h>
25
#include <drizzled/sql_plugin.h>
27
26
#include <drizzled/handler_structs.h>
28
#include <drizzled/identifier.h>
29
#include <drizzled/message.h>
30
#include <drizzled/message/cache.h>
31
#include <drizzled/plugin.h>
32
#include <drizzled/plugin/monitored_in_transaction.h>
33
#include <drizzled/plugin/plugin.h>
34
#include <drizzled/sql_string.h>
27
#include <drizzled/message/table.pb.h>
28
#include <drizzled/registry.h>
41
#include <drizzled/visibility.h>
49
typedef struct st_hash HASH;
40
typedef struct st_mysql_lex_string LEX_STRING;
52
41
typedef bool (stat_print_fn)(Session *session, const char *type, uint32_t type_len,
53
42
const char *file, uint32_t file_len,
54
43
const char *status, uint32_t status_len);
44
enum ha_stat_type { HA_ENGINE_STATUS, HA_ENGINE_LOGS, HA_ENGINE_MUTEX };
56
46
/* Possible flags of a StorageEngine (there can be 32 of them) */
57
47
enum engine_flag_bits {
58
48
HTON_BIT_ALTER_NOT_SUPPORTED, // Engine does not support alter
49
HTON_BIT_CAN_RECREATE, // Delete all is used for truncate
59
50
HTON_BIT_HIDDEN, // Engine does not appear in lists
51
HTON_BIT_FLUSH_AFTER_RENAME,
60
52
HTON_BIT_NOT_USER_SELECTABLE,
61
53
HTON_BIT_TEMPORARY_NOT_SUPPORTED, // Having temporary tables not supported
62
54
HTON_BIT_TEMPORARY_ONLY,
63
HTON_BIT_DOES_TRANSACTIONS,
64
HTON_BIT_STATS_RECORDS_IS_EXACT,
66
HTON_BIT_CAN_INDEX_BLOBS,
67
HTON_BIT_PRIMARY_KEY_IN_READ_INDEX,
68
HTON_BIT_PARTIAL_COLUMN_READ,
69
HTON_BIT_TABLE_SCAN_ON_INDEX,
70
HTON_BIT_FAST_KEY_READ,
73
HTON_BIT_NO_AUTO_INCREMENT,
74
HTON_BIT_DUPLICATE_POS,
75
HTON_BIT_AUTO_PART_KEY,
76
HTON_BIT_REQUIRE_PRIMARY_KEY,
77
HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE,
78
HTON_BIT_PRIMARY_KEY_REQUIRED_FOR_DELETE,
79
HTON_BIT_NO_PREFIX_CHAR_KEYS,
80
HTON_BIT_HAS_CHECKSUM,
81
HTON_BIT_SKIP_STORE_LOCK,
82
HTON_BIT_SCHEMA_DICTIONARY,
83
HTON_BIT_FOREIGN_KEYS,
55
HTON_BIT_FILE_BASED, // use for check_lowercase_names
56
HTON_BIT_HAS_DATA_DICTIONARY,
57
HTON_BIT_DATA_DIR, // Engine supports data directory option
58
HTON_BIT_INDEX_DIR, // Engine supports index directory option
87
62
static const std::bitset<HTON_BIT_SIZE> HTON_NO_FLAGS(0);
88
63
static const std::bitset<HTON_BIT_SIZE> HTON_ALTER_NOT_SUPPORTED(1 << HTON_BIT_ALTER_NOT_SUPPORTED);
64
static const std::bitset<HTON_BIT_SIZE> HTON_CAN_RECREATE(1 << HTON_BIT_CAN_RECREATE);
89
65
static const std::bitset<HTON_BIT_SIZE> HTON_HIDDEN(1 << HTON_BIT_HIDDEN);
66
static const std::bitset<HTON_BIT_SIZE> HTON_FLUSH_AFTER_RENAME(1 << HTON_BIT_FLUSH_AFTER_RENAME);
90
67
static const std::bitset<HTON_BIT_SIZE> HTON_NOT_USER_SELECTABLE(1 << HTON_BIT_NOT_USER_SELECTABLE);
91
68
static const std::bitset<HTON_BIT_SIZE> HTON_TEMPORARY_NOT_SUPPORTED(1 << HTON_BIT_TEMPORARY_NOT_SUPPORTED);
92
69
static const std::bitset<HTON_BIT_SIZE> HTON_TEMPORARY_ONLY(1 << HTON_BIT_TEMPORARY_ONLY);
93
static const std::bitset<HTON_BIT_SIZE> HTON_HAS_DOES_TRANSACTIONS(1 << HTON_BIT_DOES_TRANSACTIONS);
94
static const std::bitset<HTON_BIT_SIZE> HTON_STATS_RECORDS_IS_EXACT(1 << HTON_BIT_STATS_RECORDS_IS_EXACT);
95
static const std::bitset<HTON_BIT_SIZE> HTON_NULL_IN_KEY(1 << HTON_BIT_NULL_IN_KEY);
96
static const std::bitset<HTON_BIT_SIZE> HTON_CAN_INDEX_BLOBS(1 << HTON_BIT_CAN_INDEX_BLOBS);
97
static const std::bitset<HTON_BIT_SIZE> HTON_PRIMARY_KEY_IN_READ_INDEX(1 << HTON_BIT_PRIMARY_KEY_IN_READ_INDEX);
98
static const std::bitset<HTON_BIT_SIZE> HTON_PARTIAL_COLUMN_READ(1 << HTON_BIT_PARTIAL_COLUMN_READ);
99
static const std::bitset<HTON_BIT_SIZE> HTON_TABLE_SCAN_ON_INDEX(1 << HTON_BIT_TABLE_SCAN_ON_INDEX);
100
static const std::bitset<HTON_BIT_SIZE> HTON_FAST_KEY_READ(1 << HTON_BIT_FAST_KEY_READ);
101
static const std::bitset<HTON_BIT_SIZE> HTON_NO_BLOBS(1 << HTON_BIT_NO_BLOBS);
102
static const std::bitset<HTON_BIT_SIZE> HTON_HAS_RECORDS(1 << HTON_BIT_HAS_RECORDS);
103
static const std::bitset<HTON_BIT_SIZE> HTON_NO_AUTO_INCREMENT(1 << HTON_BIT_NO_AUTO_INCREMENT);
104
static const std::bitset<HTON_BIT_SIZE> HTON_DUPLICATE_POS(1 << HTON_BIT_DUPLICATE_POS);
105
static const std::bitset<HTON_BIT_SIZE> HTON_AUTO_PART_KEY(1 << HTON_BIT_AUTO_PART_KEY);
106
static const std::bitset<HTON_BIT_SIZE> HTON_REQUIRE_PRIMARY_KEY(1 << HTON_BIT_REQUIRE_PRIMARY_KEY);
107
static const std::bitset<HTON_BIT_SIZE> HTON_REQUIRES_KEY_COLUMNS_FOR_DELETE(1 << HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE);
108
static const std::bitset<HTON_BIT_SIZE> HTON_PRIMARY_KEY_REQUIRED_FOR_DELETE(1 << HTON_BIT_PRIMARY_KEY_REQUIRED_FOR_DELETE);
109
static const std::bitset<HTON_BIT_SIZE> HTON_NO_PREFIX_CHAR_KEYS(1 << HTON_BIT_NO_PREFIX_CHAR_KEYS);
110
static const std::bitset<HTON_BIT_SIZE> HTON_HAS_CHECKSUM(1 << HTON_BIT_HAS_CHECKSUM);
111
static const std::bitset<HTON_BIT_SIZE> HTON_SKIP_STORE_LOCK(1 << HTON_BIT_SKIP_STORE_LOCK);
112
static const std::bitset<HTON_BIT_SIZE> HTON_HAS_SCHEMA_DICTIONARY(1 << HTON_BIT_SCHEMA_DICTIONARY);
113
static const std::bitset<HTON_BIT_SIZE> HTON_HAS_FOREIGN_KEYS(1 << HTON_BIT_FOREIGN_KEYS);
70
static const std::bitset<HTON_BIT_SIZE> HTON_FILE_BASED(1 << HTON_BIT_FILE_BASED);
71
static const std::bitset<HTON_BIT_SIZE> HTON_HAS_DATA_DICTIONARY(1 << HTON_BIT_HAS_DATA_DICTIONARY);
72
static const std::bitset<HTON_BIT_SIZE> HTON_DATA_DIR(1 << HTON_BIT_DATA_DIR);
73
static const std::bitset<HTON_BIT_SIZE> HTON_INDEX_DIR(1 << HTON_BIT_INDEX_DIR);
117
class NamedSavepoint;
122
typedef std::vector<StorageEngine *> EngineVector;
124
typedef std::set<std::string> TableNameList;
126
extern const std::string UNKNOWN_STRING;
127
extern DRIZZLED_API const std::string DEFAULT_DEFINITION_FILE_EXT;
76
class TableNameIteratorImplementation;
131
79
StorageEngine is a singleton structure - one instance per storage engine -
132
80
to provide access to storage engine functionality that works on the
133
"global" level (unlike Cursor class that works on a per-table basis)
81
"global" level (unlike handler class that works on a per-table basis)
135
83
usually StorageEngine instance is defined statically in ha_xxx.cc as
137
85
static StorageEngine { ... } xxx_engine;
87
savepoint_*, prepare, recover, and *_by_xid pointers can be 0.
139
class DRIZZLED_API StorageEngine :
141
public MonitoredInTransaction
143
friend class SEAPITester;
145
typedef uint64_t Table_flags;
148
static EngineVector &getSchemaEngines();
149
const std::bitset<HTON_BIT_SIZE> flags; /* global Cursor flags */
152
virtual void setTransactionReadWrite(Session& session);
155
* Indicates to a storage engine the start of a
158
virtual void doStartStatement(Session *session)
164
* Indicates to a storage engine the end of
165
* the current SQL statement in the supplied
168
virtual void doEndStatement(Session *session)
174
std::string table_definition_ext;
177
const std::string& getTableDefinitionFileExtension()
179
return table_definition_ext;
92
Name used for storage engine.
94
const std::string name;
95
const bool two_phase_commit;
98
const std::bitset<HTON_BIT_SIZE> flags; /* global handler flags */
100
to store per-savepoint data storage engine is provided with an area
101
of a requested size (0 is ok here).
102
savepoint_offset must be initialized statically to the size of
103
the needed memory to store per-savepoint information.
104
After xxx_init it is changed to be an offset to savepoint storage
105
area and need not be used by storage engine.
106
see binlog_engine and binlog_savepoint_set/rollback for an example.
108
size_t savepoint_offset;
109
size_t orig_savepoint_offset;
183
110
std::vector<std::string> aliases;
112
void setTransactionReadWrite(Session* session);
117
* Implementing classes should override these to provide savepoint
120
virtual int savepoint_set_hook(Session *, void *) { return 0; }
122
virtual int savepoint_rollback_hook(Session *, void *) { return 0; }
124
virtual int savepoint_release_hook(Session *, void *) { return 0; }
186
const std::vector<std::string>& getAliases() const
128
StorageEngine(const std::string name_arg,
129
const std::bitset<HTON_BIT_SIZE> &flags_arg= HTON_NO_FLAGS,
130
size_t savepoint_offset_arg= 0,
131
bool support_2pc= false);
133
virtual ~StorageEngine();
135
static int getTableProto(const char* path,
136
drizzled::message::Table *table_proto);
138
virtual int getTableProtoImplementation(const char* path,
139
drizzled::message::Table *table_proto)
147
each storage engine has it's own memory area (actually a pointer)
148
in the session, for storing per-connection information.
151
session->ha_data[xxx_engine.slot]
153
slot number is initialized by MySQL after xxx_init() is called.
157
inline uint32_t getSlot (void) { return slot; }
158
inline void setSlot (uint32_t value) { slot= value; }
160
const std::vector<std::string>& getAliases()
238
188
return flags.test(flag);
241
// @todo match check_flag interface
242
virtual uint32_t index_flags(enum ha_key_alg) const { return 0; }
243
virtual void startStatement(Session *session)
245
doStartStatement(session);
247
virtual void endStatement(Session *session)
249
doEndStatement(session);
191
void enable() { enabled= true; }
192
void disable() { enabled= false; }
194
std::string getName() const { return name; }
253
* Called during Session::cleanup() for all engines
197
StorageEngine methods:
199
close_connection is only called if
200
session->ha_data[xxx_engine.slot] is non-zero, so even if you don't need
201
this storage area - set it to something, so that MySQL would know
202
this storage engine was accessed in this connection
255
204
virtual int close_connection(Session *)
260
virtual Cursor *create(Table &)= 0;
209
'all' is true if it's a real commit, that makes persistent changes
210
'all' is false if it's not in fact a commit but an end of the
211
statement that is part of the transaction.
212
NOTE 'all' is also false in auto-commit mode where 'end of statement'
213
and 'real commit' mean the same event.
215
virtual int commit(Session *, bool)
220
virtual int rollback(Session *, bool)
226
The void * points to an uninitialized storage area of requested size
227
(see savepoint_offset description)
229
int savepoint_set(Session *session, void *sp)
231
return savepoint_set_hook(session, (unsigned char *)sp+savepoint_offset);
235
The void * points to a storage area, that was earlier passed
236
to the savepoint_set call
238
int savepoint_rollback(Session *session, void *sp)
240
return savepoint_rollback_hook(session,
241
(unsigned char *)sp+savepoint_offset);
244
int savepoint_release(Session *session, void *sp)
246
return savepoint_release_hook(session,
247
(unsigned char *)sp+savepoint_offset);
250
virtual int prepare(Session *, bool) { return 0; }
251
virtual int recover(XID *, uint32_t) { return 0; }
252
virtual int commit_by_xid(XID *) { return 0; }
253
virtual int rollback_by_xid(XID *) { return 0; }
254
virtual handler *create(TableShare *, MEM_ROOT *)= 0;
256
virtual void drop_database(char*) { }
257
virtual int start_consistent_snapshot(Session *) { return 0; }
262
258
virtual bool flush_logs() { return false; }
263
259
virtual bool show_status(Session *, stat_print_fn *, enum ha_stat_type)
264
/* args: current_session, tables, cond */
265
virtual int fill_files_table(Session *, TableList *,
266
Item *) { return 0; }
267
virtual int release_temporary_latches(Session *) { return false; }
269
270
If frm_error() is called then we will use this to find out what file
270
271
extentions exist for the storage engine. This is also used by the default
271
rename_table and delete_table method in Cursor.cc.
272
rename_table and delete_table method in handler.cc.
273
274
For engines that have two file name extentions (separate meta/index file
274
275
and data file), the order of elements is relevant. First element of engine
279
280
virtual const char **bas_ext() const =0;
282
virtual int doCreateTable(Session &session,
284
const drizzled::identifier::Table &identifier,
285
message::Table &message)= 0;
287
virtual int doRenameTable(Session &session,
288
const drizzled::identifier::Table &from, const drizzled::identifier::Table &to)= 0;
290
virtual int doDropTable(Session &session,
291
const drizzled::identifier::Table &identifier)= 0;
293
virtual void doGetTableIdentifiers(CachedDirectory &directory,
294
const drizzled::identifier::Schema &schema_identifier,
295
identifier::Table::vector &set_of_identifiers)= 0;
297
virtual bool doDoesTableExist(Session& session, const drizzled::identifier::Table &identifier);
299
virtual bool doCanCreateTable(const drizzled::identifier::Table &identifier)
300
{ (void)identifier; return true; }
304
friend class AddSchemaNames;
305
friend class AddTableIdentifier;
306
friend class AlterSchema;
307
friend class CanCreateTable;
308
friend class CreateSchema;
309
friend class DropSchema;
310
friend class DropTable;
311
friend class DropTables;
312
friend class FindEngineByName;
313
friend class Ha_delete_table_error_handler;
314
friend class StorageEngineCloseConnection;
315
friend class StorageEngineDoesTableExist;
316
friend class StorageEngineGetSchemaDefinition;
317
friend class StorageEngineGetTableDefinition;
318
friend class DropTableByIdentifier;
320
int renameTable(Session &session, const drizzled::identifier::Table &from, const drizzled::identifier::Table &to);
322
/* Class Methods for operating on plugin */
323
static bool addPlugin(plugin::StorageEngine *engine);
324
static void removePlugin(plugin::StorageEngine *engine);
326
static message::table::shared_ptr getTableMessage(Session& session,
327
const drizzled::identifier::Table &identifier,
328
bool include_temporary_tables= true);
329
static bool doesTableExist(Session &session,
330
const drizzled::identifier::Table &identifier,
331
bool include_temporary_tables= true);
333
static plugin::StorageEngine *findByName(const std::string &find_str);
334
static plugin::StorageEngine *findByName(Session& session, const std::string &find_str);
336
static void closeConnection(Session* session);
337
static void dropDatabase(char* path);
338
static bool flushLogs(plugin::StorageEngine *db_type);
340
static bool dropTable(Session& session,
341
const drizzled::identifier::Table &identifier);
342
static bool dropTable(Session& session,
343
const drizzled::identifier::Table &identifier,
344
drizzled::error_t &error);
346
static bool dropTable(Session& session,
347
StorageEngine &engine,
348
identifier::Table::const_reference identifier,
349
drizzled::error_t &error);
351
static void getIdentifiers(Session &session,
352
const identifier::Schema &schema_identifier,
353
identifier::Table::vector &set_of_identifiers);
355
// Check to see if any SE objects to creation.
356
static bool canCreateTable(const drizzled::identifier::Table &identifier);
358
// @note All schema methods defined here
359
static void getIdentifiers(Session &session, identifier::Schema::vector &schemas);
360
static message::schema::shared_ptr getSchemaDefinition(const drizzled::identifier::Table &identifier);
361
static message::schema::shared_ptr getSchemaDefinition(const drizzled::identifier::Schema &identifier);
362
static bool doesSchemaExist(const drizzled::identifier::Schema &identifier);
363
static const CHARSET_INFO *getSchemaCollation(const drizzled::identifier::Schema &identifier);
364
static bool createSchema(const drizzled::message::Schema &schema_message);
365
static bool dropSchema(Session &session,
366
identifier::Schema::const_reference identifier,
367
message::schema::const_reference schema_message);
368
static bool alterSchema(const drizzled::message::Schema &schema_message);
370
// @note make private/protected
372
virtual void doGetSchemaIdentifiers(identifier::Schema::vector&)
375
virtual drizzled::message::schema::shared_ptr doGetSchemaDefinition(const drizzled::identifier::Schema&)
377
return drizzled::message::schema::shared_ptr();
380
virtual bool doCreateSchema(const drizzled::message::Schema&)
383
virtual bool doAlterSchema(const drizzled::message::Schema&)
386
virtual bool doDropSchema(const drizzled::identifier::Schema&)
390
static inline const std::string &resolveName(const StorageEngine *engine)
392
return engine == NULL ? UNKNOWN_STRING : engine->getName();
395
static bool createTable(Session &session,
396
const identifier::Table &identifier,
397
message::Table& table_message);
399
static void removeLostTemporaryTables(Session &session, const char *directory);
401
Cursor *getCursor(Table &share);
403
uint32_t max_record_length() const
404
{ return std::min(HA_MAX_REC_LENGTH, max_supported_record_length()); }
405
uint32_t max_keys() const
406
{ return std::min(MAX_KEY, max_supported_keys()); }
407
uint32_t max_key_parts() const
408
{ return std::min(MAX_REF_PARTS, max_supported_key_parts()); }
409
uint32_t max_key_length() const
410
{ return std::min(MAX_KEY_LENGTH, max_supported_key_length()); }
411
uint32_t max_key_part_length(void) const
412
{ return std::min(MAX_KEY_LENGTH, max_supported_key_part_length()); }
414
virtual uint32_t max_supported_record_length(void) const
415
{ return HA_MAX_REC_LENGTH; }
416
virtual uint32_t max_supported_keys(void) const { return 0; }
417
virtual uint32_t max_supported_key_parts(void) const { return MAX_REF_PARTS; }
418
virtual uint32_t max_supported_key_length(void) const { return MAX_KEY_LENGTH; }
419
virtual uint32_t max_supported_key_part_length(void) const { return 255; }
421
/* TODO-> Make private */
423
static int deleteDefinitionFromPath(const drizzled::identifier::Table &identifier);
424
static int renameDefinitionFromPath(const drizzled::identifier::Table &dest, const drizzled::identifier::Table &src);
425
static int writeDefinitionFromPath(const drizzled::identifier::Table &identifier, message::Table &proto);
426
static bool readTableFile(const std::string &path, message::Table &table_message);
430
* The below are simple virtual overrides for the plugin::MonitoredInTransaction
433
virtual bool participatesInSqlTransaction() const
435
return false; /* plugin::StorageEngine is non-transactional in terms of SQL */
437
virtual bool participatesInXaTransaction() const
439
return false; /* plugin::StorageEngine is non-transactional in terms of XA */
441
virtual bool alwaysRegisterForXaTransaction() const
446
virtual bool validateCreateTableOption(const std::string &key, const std::string &state)
454
virtual bool validateCreateSchemaOption(const std::string &key, const std::string &state)
463
std::ostream& operator<<(std::ostream& output, const StorageEngine &engine);
465
} /* namespace plugin */
466
} /* namespace drizzled */
283
virtual int createTableImplementation(Session *session,
284
const char *table_name,
286
HA_CREATE_INFO *create_info,
287
drizzled::message::Table* proto)= 0;
289
virtual int renameTableImplementation(Session* session,
290
const char *from, const char *to);
292
virtual int deleteTableImplementation(Session* session,
293
const std::string table_path);
296
int createTable(Session *session, const char *path, Table *table_arg,
297
HA_CREATE_INFO *create_info,
298
drizzled::message::Table *proto)
300
char name_buff[FN_REFLEN];
301
const char *table_name;
303
table_name= checkLowercaseNames(path, name_buff);
305
setTransactionReadWrite(session);
307
return createTableImplementation(session, table_name, table_arg,
311
int renameTable(Session *session, const char *from, const char *to)
313
setTransactionReadWrite(session);
315
return renameTableImplementation(session, from, to);
318
int deleteTable(Session* session, const std::string table_path)
320
setTransactionReadWrite(session);
322
return deleteTableImplementation(session, table_path);
325
const char *checkLowercaseNames(const char *path, char *tmp_path);
327
virtual TableNameIteratorImplementation* tableNameIterator(const std::string &database)
334
class TableNameIteratorImplementation
339
TableNameIteratorImplementation(const std::string &database) : db(database)
341
virtual ~TableNameIteratorImplementation() {};
343
virtual int next(std::string *name)= 0;
347
class TableNameIterator
350
drizzled::Registry<StorageEngine *>::iterator engine_iter;
351
TableNameIteratorImplementation *current_implementation;
352
TableNameIteratorImplementation *default_implementation;
353
std::string database;
355
TableNameIterator(const std::string &db);
356
~TableNameIterator();
358
int next(std::string *name);
362
StorageEngine *ha_default_storage_engine(Session *session);
363
StorageEngine *ha_resolve_by_name(Session *session, std::string find_str);
365
handler *get_new_handler(TableShare *share, MEM_ROOT *alloc,
366
StorageEngine *db_type);
367
const std::string ha_resolve_storage_engine_name(const StorageEngine *db_type);
468
369
#endif /* DRIZZLED_PLUGIN_STORAGE_ENGINE_H */