23
23
instance of table share per one table in the database.
26
#ifndef DRIZZLED_TABLE_INSTANCE_BASE_H
27
#define DRIZZLED_TABLE_INSTANCE_BASE_H
31
#include <boost/unordered_map.hpp>
32
#include <boost/thread/condition_variable.hpp>
33
#include <boost/dynamic_bitset.hpp>
34
#include <boost/shared_ptr.hpp>
35
#include <boost/scoped_ptr.hpp>
37
#include "drizzled/typelib.h"
38
#include "drizzled/memory/root.h"
39
#include "drizzled/message.h"
40
#include "drizzled/util/string.h"
42
#include "drizzled/lex_string.h"
43
#include "drizzled/key_map.h"
45
#include "drizzled/table/cache.h"
47
#include <drizzled/field.h>
53
const static std::string NO_PROTOBUFFER_AVAILABLE("NO PROTOBUFFER AVAILABLE");
57
class EventObserverList;
69
typedef std::vector<std::string> StringVector;
72
typedef boost::shared_ptr<TableShare> shared_ptr;
73
typedef std::vector <shared_ptr> vector;
75
TableShare(const identifier::Table::Type type_arg);
77
TableShare(const identifier::Table &identifier, const identifier::Table::Key &key); // Used by placeholder
79
TableShare(const identifier::Table &identifier); // Just used during createTable()
81
TableShare(const identifier::Table::Type type_arg,
82
const identifier::Table &identifier,
83
char *path_arg= NULL, uint32_t path_length_arg= 0); // Shares for cache
85
virtual ~TableShare();
35
} /* Remove gcc warning */
37
TableShare(const char *key,
38
uint32_t key_length, const char *new_table_name,
41
init(key, key_length, new_table_name, new_path);
88
44
/** Category of this table. */
89
45
enum_table_category table_category;
92
bool isTemporaryCategory() const
94
return (table_category == TABLE_CATEGORY_TEMPORARY);
97
void setTableCategory(enum_table_category arg)
47
uint32_t open_count; /* Number of tables in open list */
102
49
/* The following is copied to each Table on OPEN */
103
typedef std::vector<Field *> Fields;
109
const Fields getFields() const
119
Field ** getFields(bool)
124
void setFields(uint32_t arg)
129
uint32_t positionFields(Field **arg) const
131
return (arg - (Field **)&_fields[0]);
134
void pushField(Field *arg)
137
_fields.push_back(arg);
140
51
Field **found_next_number_field;
143
52
Field *timestamp_field; /* Used only during open */
147
Field *getTimestampField() const /* Used only during open */
149
return timestamp_field;
152
void setTimestampField(Field *arg) /* Used only during open */
154
timestamp_field= arg;
159
KeyInfo *key_info; /* data of keys in database */
162
KeyInfo &getKeyInfo(uint32_t arg) const
164
return key_info[arg];
166
std::vector<uint> blob_field; /* Index to blobs in Field arrray*/
53
KEY *key_info; /* data of keys in database */
54
uint *blob_field; /* Index to blobs in Field arrray*/
169
56
/* hash of field names (contains pointers to elements of field array) */
170
typedef boost::unordered_map < std::string, Field **, util::insensitive_hash, util::insensitive_equal_to> FieldMap;
171
typedef std::pair< std::string, Field ** > FieldMapPair;
172
FieldMap name_hash; /* hash of field names */
175
size_t getNamedFieldSize() const
177
return name_hash.size();
180
Field **getNamedField(const std::string &arg)
182
FieldMap::iterator iter= name_hash.find(arg);
184
if (iter == name_hash.end())
187
return (*iter).second;
191
memory::Root mem_root;
193
void *alloc_root(size_t arg)
195
return mem_root.alloc_root(arg);
198
char *strmake_root(const char *str_arg, size_t len_arg)
200
return mem_root.strmake_root(str_arg, len_arg);
203
memory::Root *getMemRoot()
208
std::vector<std::string> _keynames;
210
void addKeyName(std::string arg)
212
std::transform(arg.begin(), arg.end(),
213
arg.begin(), ::toupper);
214
_keynames.push_back(arg);
218
bool doesKeyNameExist(const char *name_arg, uint32_t name_length, uint32_t &position) const
220
return doesKeyNameExist(std::string(name_arg, name_length), position);
223
bool doesKeyNameExist(std::string arg, uint32_t &position) const
225
std::transform(arg.begin(), arg.end(),
226
arg.begin(), ::toupper);
228
std::vector<std::string>::const_iterator iter= std::find(_keynames.begin(), _keynames.end(), arg);
230
if (iter == _keynames.end())
232
position= UINT32_MAX; //historical, required for finding primary key from unique
236
position= iter - _keynames.begin();
242
std::vector<TYPELIB> intervals; /* pointer to interval info */
248
virtual void unlock()
252
std::vector<unsigned char> default_values; /* row with default values */
255
// @note This needs to be made to be const in the future
256
unsigned char *getDefaultValues()
258
return &default_values[0];
260
void resizeDefaultValues(size_t arg)
262
default_values.resize(arg);
265
const charset_info_st *table_charset; /* Default charset of string fields */
267
boost::dynamic_bitset<> all_set;
57
HASH name_hash; /* hash of field names */
59
TYPELIB keynames; /* Pointers to keynames */
60
TYPELIB fieldnames; /* Pointer to fieldnames */
61
TYPELIB *intervals; /* pointer to interval info */
62
pthread_mutex_t mutex; /* For locking the share */
63
pthread_cond_t cond; /* To signal that share is ready */
66
unsigned char *default_values; /* row with default values */
67
const CHARSET_INFO *table_charset; /* Default charset of string fields */
270
71
Key which is used for looking-up table in table cache and in the list
271
72
of thread's temporary tables. Has the form of:
276
77
should correspond to each other.
277
78
To ensure this one can use set_table_cache() methods.
280
identifier::Table::Key private_key_for_cache; // This will not exist in the final design.
281
std::vector<char> private_normalized_path; // This will not exist in the final design.
80
LEX_STRING table_cache_key;
282
81
LEX_STRING db; /* Pointer to db */
283
82
LEX_STRING table_name; /* Table name (for open) */
284
LEX_STRING path; /* Path to table (from datadir) */
83
LEX_STRING path; /* Path to .frm file (from datadir) */
285
84
LEX_STRING normalized_path; /* unpack_filename(path) */
289
const char *getNormalizedPath() const
291
return normalized_path.str;
294
const char *getPath() const
299
const identifier::Table::Key& getCacheKey() const // This should never be called when we aren't looking at a cache.
301
assert(private_key_for_cache.size());
302
return private_key_for_cache;
305
size_t getCacheKeySize() const
307
return private_key_for_cache.size();
311
void setPath(char *str_arg, uint32_t size_arg)
314
path.length= size_arg;
317
void setNormalizedPath(char *str_arg, uint32_t size_arg)
319
normalized_path.str= str_arg;
320
normalized_path.length= size_arg;
325
const char *getTableName() const
327
return table_name.str;
330
uint32_t getTableNameSize() const
332
return table_name.length;
335
const std::string &getTableName(std::string &name_arg) const
338
name_arg.append(table_name.str, table_name.length);
343
const char *getSchemaName() const
348
const std::string &getSchemaName(std::string &schema_name_arg) const
350
schema_name_arg.clear();
351
schema_name_arg.append(db.str, db.length);
353
return schema_name_arg;
85
LEX_STRING connect_string;
356
87
uint32_t block_size; /* create information */
362
uint64_t getVersion() const
367
void refreshVersion();
375
89
uint32_t timestamp_offset; /* Set to offset+1 of record */
377
uint32_t reclength; /* Recordlength */
378
uint32_t stored_rec_length; /* Stored record length*/
381
uint32_t sizeStoredRecord() const
383
return stored_rec_length;
386
uint32_t getRecordLength() const
391
void setRecordLength(uint32_t arg)
396
const Field_blob *getBlobFieldAt(uint32_t arg) const
398
if (arg < blob_fields)
399
return (Field_blob*) _fields[blob_field[arg]];
90
uint32_t reclength; /* Recordlength */
91
uint32_t stored_rec_length; /* Stored record length*/
92
enum row_type row_type; /* How rows are stored */
405
95
/* Max rows is a hint to HEAP during a create tmp table */
406
96
uint64_t max_rows;
408
boost::scoped_ptr<message::Table> _table_message;
98
drizzled::message::Table *table_proto;
412
@note Without a _table_message, we assume we are building a STANDARD table.
413
This will be modified once we use Identifiers in the Share itself.
415
message::Table::TableType getTableType() const
417
return getTableMessage() ? getTableMessage()->type() : message::Table::STANDARD;
420
const std::string &getTableTypeAsString() const
422
if (getTableMessage())
423
return message::type(getTableMessage()->type());
425
return NO_PROTOBUFFER_AVAILABLE;
428
101
/* This is only used in one location currently */
429
inline message::Table *getTableMessage() const
431
return _table_message.get();
434
void setTableMessage(const message::Table &arg)
436
assert(not getTableMessage());
437
_table_message.reset(new(std::nothrow) message::Table(arg));
440
const message::Table::Field &field(int32_t field_position) const
442
assert(getTableMessage());
443
return getTableMessage()->field(field_position);
446
inline bool hasComment() const
448
return (getTableMessage()) ? getTableMessage()->options().has_comment() : false;
102
inline void setTableProto(drizzled::message::Table *arg)
104
assert(table_proto == NULL);
108
inline bool hasComment()
110
return (table_proto) ? table_proto->options().has_comment() : false;
451
113
inline const char *getComment()
453
return (getTableMessage() && getTableMessage()->has_options()) ? getTableMessage()->options().comment().c_str() : NULL;
115
return (table_proto) ? table_proto->options().comment().c_str() : NULL;
456
inline uint32_t getCommentLength() const
118
inline uint32_t getCommentLength()
458
return (getTableMessage()) ? getTableMessage()->options().comment().length() : 0;
120
return (table_proto) ? table_proto->options().comment().length() : 0;
461
inline uint64_t getMaxRows() const
123
inline uint64_t getMaxRows()
472
* Returns true if the supplied Field object
473
* is part of the table's primary key.
475
bool fieldInPrimaryKey(Field *field) const;
477
plugin::StorageEngine *storage_engine; /* storage engine plugin */
478
inline plugin::StorageEngine *db_type() const /* table_type for handler */
480
return storage_engine;
482
inline plugin::StorageEngine *getEngine() const /* table_type for handler */
484
return storage_engine;
488
identifier::Table::Type tmp_table;
491
identifier::Table::Type getType() const
497
uint32_t _ref_count; /* How many Table objects uses this */
500
uint32_t getTableCount() const
505
void incrementTableCount()
512
uint32_t decrementTableCount()
133
StorageEngine *storage_engine; /* storage engine plugin */
134
inline StorageEngine *db_type() const /* table_type for handler */
136
return storage_engine;
138
enum tmp_table_type tmp_table;
140
uint32_t ref_count; /* How many Table objects uses this */
141
uint32_t key_block_size; /* create key_block_size, if used */
517
142
uint32_t null_bytes;
518
143
uint32_t last_null_bit_pos;
520
uint32_t _field_size; /* Number of fields */
523
void setFieldSize(uint32_t arg)
528
uint32_t sizeFields() const
144
uint32_t fields; /* Number of fields */
533
145
uint32_t rec_buff_length; /* Size of table->record[] buffer */
536
uint32_t sizeKeys() const
146
uint32_t keys, key_parts;
541
147
uint32_t max_key_length, max_unique_length, total_key_length;
542
148
uint32_t uniques; /* Number of UNIQUE index */
543
149
uint32_t null_fields; /* number of null fields */
544
150
uint32_t blob_fields; /* number of blob fields */
546
bool has_variable_width; /* number of varchar fields */
549
bool hasVariableWidth() const
551
return has_variable_width; // We should calculate this.
553
void setVariableWidth()
555
has_variable_width= true;
151
uint32_t timestamp_field_offset; /* Field number for timestamp field */
152
uint32_t varchar_fields; /* number of varchar fields */
557
153
uint32_t db_create_options; /* Create options from database */
558
154
uint32_t db_options_in_use; /* Options in use */
559
155
uint32_t db_record_offset; /* if HA_REC_IN_SEQ */
560
156
uint32_t rowid_field_offset; /* Field_nr +1 to rowid field */
564
* Currently the replication services component uses
565
* the primary_key member to determine which field is the table's
566
* primary key. However, as it exists, because this member is scalar, it
567
* only supports a single-column primary key. Is there a better way
568
* to ask for the fields which are in a primary key?
157
/* Index of auto-updated TIMESTAMP field in field array */
571
158
uint32_t primary_key;
574
uint32_t getPrimaryKey() const
579
bool hasPrimaryKey() const
581
return primary_key != MAX_KEY;
584
/* Index of auto-updated TIMESTAMP field in field array */
585
159
uint32_t next_number_index; /* autoincrement key number */
586
160
uint32_t next_number_key_offset; /* autoinc keypart offset in a key */
587
161
uint32_t next_number_keypart; /* autoinc keypart number in a key */
588
162
uint32_t error, open_errno, errarg; /* error from open_table_def() */
163
uint32_t column_bitmap_size;
591
165
uint8_t blob_ptr_size; /* 4 or 8 */
594
uint8_t sizeBlobPtr() const
596
return blob_ptr_size;
599
166
bool db_low_byte_first; /* Portable row format */
169
bool replace_with_name_lock;
170
bool waiting_on_cond; /* Protection against free */
602
173
Set of keys in use, implemented as a Bitmap.
605
176
key_map keys_in_use;
606
177
key_map keys_for_keyread;
609
event_observers is a class containing all the event plugins that have
610
registered an interest in this table.
612
virtual plugin::EventObserverList *getTableObservers()
617
virtual void setTableObservers(plugin::EventObserverList *)
621
Set share's identifier information.
180
Set share's table cache key and update its db and table name appropriately.
183
set_table_cache_key()
184
key_buff Buffer with already built table cache key to be
185
referenced from share.
186
key_length Key length.
629
void setIdentifier(const identifier::Table &identifier_arg);
189
Since 'key_buff' buffer will be referenced from share it should has same
190
life-time as share itself.
191
This method automatically ensures that TableShare::table_name/db have
192
appropriate values by using table cache key as their source.
195
void set_table_cache_key(char *key_buff, uint32_t key_length)
197
table_cache_key.str= key_buff;
198
table_cache_key.length= key_length;
200
Let us use the fact that the key is "db/0/table_name/0" + optional
201
part for temporary tables.
203
db.str= table_cache_key.str;
204
db.length= strlen(db.str);
205
table_name.str= db.str + db.length + 1;
206
table_name.length= strlen(table_name.str);
211
Set share's table cache key and update its db and table name appropriately.
214
set_table_cache_key()
215
key_buff Buffer to be used as storage for table cache key
216
(should be at least key_length bytes).
217
key Value for table cache key.
218
key_length Key length.
221
Since 'key_buff' buffer will be used as storage for table cache key
222
it should has same life-time as share itself.
225
void set_table_cache_key(char *key_buff, const char *key, uint32_t key_length)
227
memcpy(key_buff, key, key_length);
228
set_table_cache_key(key_buff, key_length);
231
inline bool honor_global_locks()
233
return (table_category == TABLE_CATEGORY_USER);
632
238
Initialize share for temporary tables
638
244
must start with db name.
639
245
key_length Length of key
640
246
table_name Table name
641
path Path to table (possible in lower case)
247
path Path to file (possible in lower case) without .frm
250
This is different from alloc_table_share() because temporary tables
251
don't have to be shared between threads or put into the table def
252
cache, so we can do some things notable simpler and faster
254
If table is not put in session->temporary_tables (happens only when
255
one uses OPEN TEMPORARY) then one can specify 'db' as key and
256
use key_length= 0 as neither table_cache_key or key_length will be used).
648
264
void init(const char *new_table_name,
649
const char *new_path);
265
const char *new_path)
267
init("", 0, new_table_name, new_path);
270
void init(const char *key,
271
uint32_t key_length, const char *new_table_name,
272
const char *new_path)
274
memset(this, 0, sizeof(TableShare));
275
init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
276
table_category= TABLE_CATEGORY_TEMPORARY;
277
tmp_table= INTERNAL_TMP_TABLE;
279
db.length= strlen(key);
280
table_cache_key.str= (char*) key;
281
table_cache_key.length= key_length;
282
table_name.str= (char*) new_table_name;
283
table_name.length= strlen(new_table_name);
284
path.str= (char*) new_path;
285
normalized_path.str= (char*) new_path;
286
path.length= normalized_path.length= strlen(new_path);
292
Free table share and memory used by it
299
share->mutex must be locked when we come here if it's not a temp table
302
void free_table_share()
304
MEM_ROOT new_mem_root;
305
assert(ref_count == 0);
308
If someone is waiting for this to be deleted, inform it about this.
309
Don't do a delete until we know that no one is refering to this anymore.
311
if (tmp_table == NO_TMP_TABLE)
313
/* share->mutex is locked in release_table_share() */
314
while (waiting_on_cond)
316
pthread_cond_broadcast(&cond);
317
pthread_cond_wait(&cond, &mutex);
319
/* No thread refers to this anymore */
320
pthread_mutex_unlock(&mutex);
321
pthread_mutex_destroy(&mutex);
322
pthread_cond_destroy(&cond);
324
hash_free(&name_hash);
326
storage_engine= NULL;
331
/* We must copy mem_root from share because share is allocated through it */
332
memcpy(&new_mem_root, &mem_root, sizeof(new_mem_root));
333
free_root(&new_mem_root, MYF(0)); // Free's share
652
336
void open_table_error(int pass_error, int db_errno, int pass_errarg);
656
static TableShare::shared_ptr getShareCreate(Session *session,
657
const identifier::Table &identifier,
660
friend std::ostream& operator<<(std::ostream& output, const TableShare &share)
662
output << "TableShare:(";
663
output << share.getSchemaName();
665
output << share.getTableName();
667
output << share.getTableTypeAsString();
669
output << share.getPath();
672
return output; // for multiple << operators.
676
friend class drizzled::table::Singular;
678
Field *make_field(const message::Table::Field &pfield,
680
uint32_t field_length,
682
unsigned char *null_pos,
683
unsigned char null_bit,
685
enum_field_types field_type,
686
const charset_info_st * field_charset,
687
Field::utype unireg_check,
689
const char *field_name);
691
Field *make_field(const message::Table::Field &pfield,
693
uint32_t field_length,
695
unsigned char *null_pos,
696
unsigned char null_bit,
698
enum_field_types field_type,
699
const charset_info_st * field_charset,
700
Field::utype unireg_check,
702
const char *field_name,
706
int open_table_def(Session& session, const identifier::Table &identifier);
708
int open_table_from_share(Session *session,
709
const identifier::Table &identifier,
711
uint32_t db_stat, uint32_t ha_open_flags,
714
int open_table_from_share_inner(Session *session,
718
int open_table_cursor_inner(const identifier::Table &identifier,
719
uint32_t db_stat, uint32_t ha_open_flags,
721
bool &error_reported);
723
bool parse_table_proto(Session& session, message::Table &table);
341
Create a table cache key
345
key Create key here (must be of size MAX_DBKEY_LENGTH)
346
table_list Table definition
349
The table cache_key is created from:
353
if the table is a tmp table, we add the following to make each tmp table
356
4 bytes for master thread id
357
4 bytes pseudo thread id
363
static inline uint32_t createKey(char *key, std::string& db_arg,
364
std::string& table_name_arg)
366
return createKey(key, db_arg.c_str(), table_name_arg.c_str());
369
static inline uint32_t createKey(char *key, const char *db_arg, const char *table_name_arg)
374
key_pos= strcpy(key_pos, db_arg) + strlen(db_arg);
375
key_pos= strcpy(key_pos+1, table_name_arg) +
376
strlen(table_name_arg);
377
key_length= (uint32_t)(key_pos-key)+1;
382
static bool cacheStart(void);
383
static void cacheStop(void);
384
static void release(TableShare *share);
385
static void release(const char *key, uint32_t key_length);
386
static TableShare *getShare(const char *db, const char *table_name);
387
static TableShare *getShare(Session *session,
388
TableList *table_list, char *key,
389
uint32_t key_length, uint32_t, int *error);
726
} /* namespace drizzled */
728
#endif /* DRIZZLED_TABLE_INSTANCE_BASE_H */