1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2009 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; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
This class is shared between different table objects. There is one
23
instance of table share per one table in the database.
26
#ifndef DRIZZLED_TABLE_SHARE_H
27
#define DRIZZLED_TABLE_SHARE_H
31
#include "drizzled/typelib.h"
32
#include "drizzled/my_hash.h"
33
#include "drizzled/memory/root.h"
34
#include "drizzled/message/table.pb.h"
39
typedef drizzled::hash_map<std::string, TableShare *> TableDefinitionCache;
41
const static std::string STANDARD_STRING("STANDARD");
42
const static std::string TEMPORARY_STRING("TEMPORARY");
43
const static std::string INTERNAL_STRING("INTERNAL");
44
const static std::string FUNCTION_STRING("FUNCTION");
50
table_category(TABLE_UNKNOWN_CATEGORY),
53
found_next_number_field(NULL),
54
timestamp_field(NULL),
64
row_type(ROW_TYPE_DEFAULT),
68
tmp_table(message::Table::STANDARD),
82
timestamp_field_offset(0),
87
rowid_field_offset(0),
90
next_number_key_offset(0),
91
next_number_keypart(0),
95
column_bitmap_size(0),
97
db_low_byte_first(false),
99
replace_with_name_lock(false),
100
waiting_on_cond(false),
107
TableShare(const char *key,
109
const char *new_table_name,
110
const char *new_path) :
111
table_category(TABLE_UNKNOWN_CATEGORY),
114
found_next_number_field(NULL),
115
timestamp_field(NULL),
119
default_values(NULL),
124
stored_rec_length(0),
125
row_type(ROW_TYPE_DEFAULT),
128
storage_engine(NULL),
129
tmp_table(message::Table::STANDARD),
132
last_null_bit_pos(0),
138
max_unique_length(0),
143
timestamp_field_offset(0),
145
db_create_options(0),
146
db_options_in_use(0),
148
rowid_field_offset(0),
150
next_number_index(0),
151
next_number_key_offset(0),
152
next_number_keypart(0),
156
column_bitmap_size(0),
158
db_low_byte_first(false),
160
replace_with_name_lock(false),
161
waiting_on_cond(false),
165
init(key, key_length, new_table_name, new_path);
168
/** Category of this table. */
169
enum_table_category table_category;
171
uint32_t open_count; /* Number of tables in open list */
173
/* The following is copied to each Table on OPEN */
175
Field **found_next_number_field;
176
Field *timestamp_field; /* Used only during open */
177
KEY *key_info; /* data of keys in database */
178
uint *blob_field; /* Index to blobs in Field arrray*/
180
/* hash of field names (contains pointers to elements of field array) */
181
HASH name_hash; /* hash of field names */
182
memory::Root mem_root;
183
TYPELIB keynames; /* Pointers to keynames */
184
TYPELIB fieldnames; /* Pointer to fieldnames */
185
TYPELIB *intervals; /* pointer to interval info */
186
pthread_mutex_t mutex; /* For locking the share */
187
pthread_cond_t cond; /* To signal that share is ready */
189
unsigned char *default_values; /* row with default values */
190
const CHARSET_INFO *table_charset; /* Default charset of string fields */
194
Key which is used for looking-up table in table cache and in the list
195
of thread's temporary tables. Has the form of:
196
"database_name\0table_name\0" + optional part for temporary tables.
198
Note that all three 'table_cache_key', 'db' and 'table_name' members
199
must be set (and be non-zero) for tables in table cache. They also
200
should correspond to each other.
201
To ensure this one can use set_table_cache() methods.
203
LEX_STRING table_cache_key;
205
LEX_STRING db; /* Pointer to db */
207
LEX_STRING table_name; /* Table name (for open) */
208
LEX_STRING path; /* Path to table (from datadir) */
209
LEX_STRING normalized_path; /* unpack_filename(path) */
211
const char *getTableName() const
213
return table_name.str;
216
const char *getPath() const
221
const std::string &getTableName(std::string &name_arg) const
224
name_arg.append(table_name.str, table_name.length);
229
const char *getSchemaName() const
234
const std::string &getSchemaName(std::string &schema_name_arg) const
236
schema_name_arg.clear();
237
schema_name_arg.append(db.str, db.length);
239
return schema_name_arg;
242
uint32_t block_size; /* create information */
245
uint64_t getVersion()
250
uint32_t timestamp_offset; /* Set to offset+1 of record */
251
uint32_t reclength; /* Recordlength */
252
uint32_t stored_rec_length; /* Stored record length*/
253
enum row_type row_type; /* How rows are stored */
255
uint32_t getRecordLength()
261
/* Max rows is a hint to HEAP during a create tmp table */
264
message::Table *table_proto;
267
const std::string &getTableTypeAsString() const
269
switch (table_proto->type())
272
case message::Table::STANDARD:
273
return STANDARD_STRING;
274
case message::Table::TEMPORARY:
275
return TEMPORARY_STRING;
276
case message::Table::INTERNAL:
277
return INTERNAL_STRING;
278
case message::Table::FUNCTION:
279
return FUNCTION_STRING;
283
/* This is only used in one location currently */
284
inline message::Table *getTableProto() const
289
inline void setTableProto(message::Table *arg)
291
assert(table_proto == NULL);
295
inline bool hasComment()
297
return (table_proto) ? table_proto->options().has_comment() : false;
300
inline const char *getComment()
302
return (table_proto && table_proto->has_options()) ? table_proto->options().comment().c_str() : NULL;
305
inline uint32_t getCommentLength()
307
return (table_proto) ? table_proto->options().comment().length() : 0;
310
inline bool hasKeyBlockSize()
312
return (table_proto) ? table_proto->options().has_key_block_size() : false;
315
inline uint32_t getKeyBlockSize()
317
return (table_proto) ? table_proto->options().key_block_size() : 0;
320
inline uint64_t getMaxRows()
325
inline void setMaxRows(uint64_t arg)
331
* Returns true if the supplied Field object
332
* is part of the table's primary key.
334
bool fieldInPrimaryKey(Field *field) const;
336
plugin::StorageEngine *storage_engine; /* storage engine plugin */
337
inline plugin::StorageEngine *db_type() const /* table_type for handler */
339
return storage_engine;
341
inline plugin::StorageEngine *getEngine() const /* table_type for handler */
343
return storage_engine;
346
TableIdentifier::Type tmp_table;
348
uint32_t ref_count; /* How many Table objects uses this */
349
uint32_t getTableCount()
355
uint32_t last_null_bit_pos;
356
uint32_t fields; /* Number of fields */
357
uint32_t rec_buff_length; /* Size of table->record[] buffer */
358
uint32_t keys, key_parts;
359
uint32_t max_key_length, max_unique_length, total_key_length;
360
uint32_t uniques; /* Number of UNIQUE index */
361
uint32_t null_fields; /* number of null fields */
362
uint32_t blob_fields; /* number of blob fields */
363
uint32_t timestamp_field_offset; /* Field number for timestamp field */
364
uint32_t varchar_fields; /* number of varchar fields */
365
uint32_t db_create_options; /* Create options from database */
366
uint32_t db_options_in_use; /* Options in use */
367
uint32_t db_record_offset; /* if HA_REC_IN_SEQ */
368
uint32_t rowid_field_offset; /* Field_nr +1 to rowid field */
372
* Currently the replication services component uses
373
* the primary_key member to determine which field is the table's
374
* primary key. However, as it exists, because this member is scalar, it
375
* only supports a single-column primary key. Is there a better way
376
* to ask for the fields which are in a primary key?
378
uint32_t primary_key;
379
/* Index of auto-updated TIMESTAMP field in field array */
380
uint32_t next_number_index; /* autoincrement key number */
381
uint32_t next_number_key_offset; /* autoinc keypart offset in a key */
382
uint32_t next_number_keypart; /* autoinc keypart number in a key */
383
uint32_t error, open_errno, errarg; /* error from open_table_def() */
384
uint32_t column_bitmap_size;
386
uint8_t blob_ptr_size; /* 4 or 8 */
387
bool db_low_byte_first; /* Portable row format */
390
bool isNameLock() const
395
bool replace_with_name_lock;
397
bool waiting_on_cond; /* Protection against free */
398
bool isWaitingOnCondition()
400
return waiting_on_cond;
404
Set of keys in use, implemented as a Bitmap.
405
Excludes keys disabled by ALTER Table ... DISABLE KEYS.
408
key_map keys_for_keyread;
411
Set share's table cache key and update its db and table name appropriately.
414
set_table_cache_key()
415
key_buff Buffer with already built table cache key to be
416
referenced from share.
417
key_length Key length.
420
Since 'key_buff' buffer will be referenced from share it should has same
421
life-time as share itself.
422
This method automatically ensures that TableShare::table_name/db have
423
appropriate values by using table cache key as their source.
426
void set_table_cache_key(char *key_buff, uint32_t key_length)
428
table_cache_key.str= key_buff;
429
table_cache_key.length= key_length;
431
Let us use the fact that the key is "db/0/table_name/0" + optional
432
part for temporary tables.
434
db.str= table_cache_key.str;
435
db.length= strlen(db.str);
436
table_name.str= db.str + db.length + 1;
437
table_name.length= strlen(table_name.str);
442
Set share's table cache key and update its db and table name appropriately.
445
set_table_cache_key()
446
key_buff Buffer to be used as storage for table cache key
447
(should be at least key_length bytes).
448
key Value for table cache key.
449
key_length Key length.
452
Since 'key_buff' buffer will be used as storage for table cache key
453
it should has same life-time as share itself.
456
void set_table_cache_key(char *key_buff, const char *key, uint32_t key_length)
458
memcpy(key_buff, key, key_length);
459
set_table_cache_key(key_buff, key_length);
462
inline bool honor_global_locks()
464
return (table_category == TABLE_CATEGORY_USER);
469
Initialize share for temporary tables
474
key Table_cache_key, as generated from create_table_def_key.
475
must start with db name.
476
key_length Length of key
477
table_name Table name
478
path Path to table (possible in lower case)
481
This is different from alloc_table_share() because temporary tables
482
don't have to be shared between threads or put into the table def
483
cache, so we can do some things notable simpler and faster
485
If table is not put in session->temporary_tables (happens only when
486
one uses OPEN TEMPORARY) then one can specify 'db' as key and
487
use key_length= 0 as neither table_cache_key or key_length will be used).
495
void init(const char *new_table_name,
496
const char *new_path)
498
init("", 0, new_table_name, new_path);
501
void init(const char *key,
502
uint32_t key_length, const char *new_table_name,
503
const char *new_path)
505
memset(this, 0, sizeof(TableShare));
506
memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
507
table_category= TABLE_CATEGORY_TEMPORARY;
508
tmp_table= message::Table::INTERNAL;
510
db.length= strlen(key);
511
table_cache_key.str= (char*) key;
512
table_cache_key.length= key_length;
513
table_name.str= (char*) new_table_name;
514
table_name.length= strlen(new_table_name);
515
path.str= (char*) new_path;
516
normalized_path.str= (char*) new_path;
517
path.length= normalized_path.length= strlen(new_path);
523
Free table share and memory used by it
530
share->mutex must be locked when we come here if it's not a temp table
533
void free_table_share()
535
memory::Root new_mem_root;
536
assert(ref_count == 0);
539
If someone is waiting for this to be deleted, inform it about this.
540
Don't do a delete until we know that no one is refering to this anymore.
542
if (tmp_table == message::Table::STANDARD)
544
/* share->mutex is locked in release_table_share() */
545
while (waiting_on_cond)
547
pthread_cond_broadcast(&cond);
548
pthread_cond_wait(&cond, &mutex);
550
/* No thread refers to this anymore */
551
pthread_mutex_unlock(&mutex);
552
pthread_mutex_destroy(&mutex);
553
pthread_cond_destroy(&cond);
555
hash_free(&name_hash);
557
storage_engine= NULL;
562
/* We must copy mem_root from share because share is allocated through it */
563
memcpy(&new_mem_root, &mem_root, sizeof(new_mem_root));
564
free_root(&new_mem_root, MYF(0)); // Free's share
567
void open_table_error(int pass_error, int db_errno, int pass_errarg);
572
Create a table cache key
576
key Create key here (must be of size MAX_DBKEY_LENGTH)
577
table_list Table definition
580
The table cache_key is created from:
584
if the table is a tmp table, we add the following to make each tmp table
587
4 bytes for master thread id
588
4 bytes pseudo thread id
593
static inline uint32_t createKey(char *key, const char *db_arg, const char *table_name_arg)
598
key_pos= strcpy(key_pos, db_arg) + strlen(db_arg);
599
key_pos= strcpy(key_pos+1, table_name_arg) +
600
strlen(table_name_arg);
601
key_length= (uint32_t)(key_pos-key)+1;
606
static inline uint32_t createKey(char *key, TableIdentifier &identifier)
611
key_pos= strcpy(key_pos, identifier.getSchemaName().c_str()) + identifier.getSchemaName().length();
612
key_pos= strcpy(key_pos + 1, identifier.getTableName().c_str()) + identifier.getTableName().length();
613
key_length= (uint32_t)(key_pos-key)+1;
618
static void cacheStart(void);
619
static void cacheStop(void);
620
static void release(TableShare *share);
621
static void release(const char *key, uint32_t key_length);
622
static TableDefinitionCache &getCache();
623
static TableShare *getShare(TableIdentifier &identifier);
624
static TableShare *getShare(Session *session,
625
TableList *table_list, char *key,
626
uint32_t key_length, uint32_t, int *error);
628
friend std::ostream& operator<<(std::ostream& output, const TableShare &share)
630
output << "TableShare:(";
631
output << share.getSchemaName();
633
output << share.getTableName();
635
output << share.getTableTypeAsString();
637
output << share.getPath();
640
return output; // for multiple << operators.
644
} /* namespace drizzled */
646
#endif /* DRIZZLED_TABLE_SHARE_H */