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/unordered_map.h>
33
#include "drizzled/typelib.h"
34
#include "drizzled/my_hash.h"
35
#include "drizzled/memory/root.h"
36
#include "drizzled/message/table.pb.h"
41
typedef unordered_map<std::string, TableShare *> TableDefinitionCache;
43
const static std::string STANDARD_STRING("STANDARD");
44
const static std::string TEMPORARY_STRING("TEMPORARY");
45
const static std::string INTERNAL_STRING("INTERNAL");
46
const static std::string FUNCTION_STRING("FUNCTION");
50
class EventObserverList;
55
typedef std::vector<std::string> StringVector;
58
table_category(TABLE_UNKNOWN_CATEGORY),
61
found_next_number_field(NULL),
62
timestamp_field(NULL),
72
row_type(ROW_TYPE_DEFAULT),
76
tmp_table(message::Table::STANDARD),
90
timestamp_field_offset(0),
95
rowid_field_offset(0),
98
next_number_key_offset(0),
99
next_number_keypart(0),
103
column_bitmap_size(0),
105
db_low_byte_first(false),
107
replace_with_name_lock(false),
108
waiting_on_cond(false),
111
event_observers(NULL),
114
memset(&name_hash, 0, sizeof(HASH));
117
memset(&all_set, 0, sizeof (MyBitmap));
118
memset(&table_cache_key, 0, sizeof(LEX_STRING));
119
memset(&db, 0, sizeof(LEX_STRING));
120
memset(&table_name, 0, sizeof(LEX_STRING));
121
memset(&path, 0, sizeof(LEX_STRING));
122
memset(&normalized_path, 0, sizeof(LEX_STRING));
127
TableShare(const char *key,
129
const char *new_table_name,
130
const char *new_path) :
131
table_category(TABLE_UNKNOWN_CATEGORY),
134
found_next_number_field(NULL),
135
timestamp_field(NULL),
139
default_values(NULL),
144
stored_rec_length(0),
145
row_type(ROW_TYPE_DEFAULT),
148
storage_engine(NULL),
149
tmp_table(message::Table::STANDARD),
152
last_null_bit_pos(0),
158
max_unique_length(0),
163
timestamp_field_offset(0),
165
db_create_options(0),
166
db_options_in_use(0),
168
rowid_field_offset(0),
170
next_number_index(0),
171
next_number_key_offset(0),
172
next_number_keypart(0),
176
column_bitmap_size(0),
178
db_low_byte_first(false),
180
replace_with_name_lock(false),
181
waiting_on_cond(false),
184
event_observers(NULL),
187
memset(&name_hash, 0, sizeof(HASH));
190
memset(&all_set, 0, sizeof (MyBitmap));
191
memset(&table_cache_key, 0, sizeof(LEX_STRING));
192
memset(&db, 0, sizeof(LEX_STRING));
193
memset(&table_name, 0, sizeof(LEX_STRING));
194
memset(&path, 0, sizeof(LEX_STRING));
195
memset(&normalized_path, 0, sizeof(LEX_STRING));
196
init(key, key_length, new_table_name, new_path);
199
TableShare(char *key, uint32_t key_length, char *path_arg= NULL, uint32_t path_length_arg= 0);
203
assert(ref_count == 0);
206
If someone is waiting for this to be deleted, inform it about this.
207
Don't do a delete until we know that no one is refering to this anymore.
209
if (tmp_table == message::Table::STANDARD)
211
/* share->mutex is locked in release_table_share() */
212
while (waiting_on_cond)
214
pthread_cond_broadcast(&cond);
215
pthread_cond_wait(&cond, &mutex);
217
/* No thread refers to this anymore */
218
pthread_mutex_unlock(&mutex);
219
pthread_mutex_destroy(&mutex);
220
pthread_cond_destroy(&cond);
222
hash_free(&name_hash);
224
storage_engine= NULL;
229
mem_root.free_root(MYF(0)); // Free's share
233
/** Category of this table. */
234
enum_table_category table_category;
236
uint32_t open_count; /* Number of tables in open list */
239
bool isTemporaryCategory() const
241
return (table_category == TABLE_CATEGORY_TEMPORARY);
244
void setTableCategory(enum_table_category arg)
249
/* The following is copied to each Table on OPEN */
259
Field **found_next_number_field;
260
Field *timestamp_field; /* Used only during open */
261
KeyInfo *key_info; /* data of keys in database */
262
uint *blob_field; /* Index to blobs in Field arrray*/
264
/* hash of field names (contains pointers to elements of field array) */
265
HASH name_hash; /* hash of field names */
267
memory::Root mem_root;
269
void *alloc_root(size_t arg)
271
return mem_root.alloc_root(arg);
274
char *strmake_root(const char *str_arg, size_t len_arg)
276
return mem_root.strmake_root(str_arg, len_arg);
279
memory::Root *getMemRoot()
285
std::vector<std::string> _keynames;
287
void addKeyName(std::string arg)
289
std::transform(arg.begin(), arg.end(),
290
arg.begin(), ::toupper);
291
_keynames.push_back(arg);
294
bool doesKeyNameExist(const char *name_arg, uint32_t name_length, uint32_t &position)
296
std::string arg(name_arg, name_length);
297
std::transform(arg.begin(), arg.end(),
298
arg.begin(), ::toupper);
300
std::vector<std::string>::iterator iter= std::find(_keynames.begin(), _keynames.end(), arg);
302
if (iter == _keynames.end())
305
position= iter - _keynames.begin();
310
bool doesKeyNameExist(std::string arg, uint32_t &position)
312
std::transform(arg.begin(), arg.end(),
313
arg.begin(), ::toupper);
315
std::vector<std::string>::iterator iter= std::find(_keynames.begin(), _keynames.end(), arg);
317
if (iter == _keynames.end())
319
position= -1; //historical, required for finding primary key from unique
323
position= iter - _keynames.begin();
329
TYPELIB *intervals; /* pointer to interval info */
332
pthread_mutex_t mutex; /* For locking the share */
333
pthread_cond_t cond; /* To signal that share is ready */
335
unsigned char *default_values; /* row with default values */
336
const CHARSET_INFO *table_charset; /* Default charset of string fields */
340
Key which is used for looking-up table in table cache and in the list
341
of thread's temporary tables. Has the form of:
342
"database_name\0table_name\0" + optional part for temporary tables.
344
Note that all three 'table_cache_key', 'db' and 'table_name' members
345
must be set (and be non-zero) for tables in table cache. They also
346
should correspond to each other.
347
To ensure this one can use set_table_cache() methods.
350
LEX_STRING table_cache_key; /* Pointer to db */
351
LEX_STRING db; /* Pointer to db */
352
LEX_STRING table_name; /* Table name (for open) */
353
LEX_STRING path; /* Path to table (from datadir) */
354
LEX_STRING normalized_path; /* unpack_filename(path) */
357
const char *getNormalizedPath()
359
return normalized_path.str;
362
const char *getPath()
367
const char *getCacheKey()
369
return table_cache_key.str;
372
size_t getCacheKeySize() const
374
return table_cache_key.length;
377
void setPath(char *str_arg, uint32_t size_arg)
380
path.length= size_arg;
383
void setNormalizedPath(char *str_arg, uint32_t size_arg)
385
normalized_path.str= str_arg;
386
normalized_path.length= size_arg;
389
const char *getTableName() const
391
return table_name.str;
394
uint32_t getTableNameSize() const
396
return table_name.length;
399
const char *getTableCacheKey() const
401
return table_cache_key.str;
404
const char *getPath() const
409
const std::string &getTableName(std::string &name_arg) const
412
name_arg.append(table_name.str, table_name.length);
417
const char *getSchemaName() const
422
const std::string &getSchemaName(std::string &schema_name_arg) const
424
schema_name_arg.clear();
425
schema_name_arg.append(db.str, db.length);
427
return schema_name_arg;
430
uint32_t block_size; /* create information */
433
uint64_t getVersion()
438
uint32_t timestamp_offset; /* Set to offset+1 of record */
439
uint32_t reclength; /* Recordlength */
440
uint32_t stored_rec_length; /* Stored record length*/
441
enum row_type row_type; /* How rows are stored */
443
uint32_t getRecordLength()
449
/* Max rows is a hint to HEAP during a create tmp table */
452
message::Table *table_proto;
455
const std::string &getTableTypeAsString() const
457
switch (table_proto->type())
460
case message::Table::STANDARD:
461
return STANDARD_STRING;
462
case message::Table::TEMPORARY:
463
return TEMPORARY_STRING;
464
case message::Table::INTERNAL:
465
return INTERNAL_STRING;
466
case message::Table::FUNCTION:
467
return FUNCTION_STRING;
471
/* This is only used in one location currently */
472
inline message::Table *getTableProto() const
477
inline void setTableProto(message::Table *arg)
479
assert(table_proto == NULL);
483
inline bool hasComment()
485
return (table_proto) ? table_proto->options().has_comment() : false;
488
inline const char *getComment()
490
return (table_proto && table_proto->has_options()) ? table_proto->options().comment().c_str() : NULL;
493
inline uint32_t getCommentLength()
495
return (table_proto) ? table_proto->options().comment().length() : 0;
498
inline uint64_t getMaxRows() const
503
inline void setMaxRows(uint64_t arg)
509
* Returns true if the supplied Field object
510
* is part of the table's primary key.
512
bool fieldInPrimaryKey(Field *field) const;
514
plugin::StorageEngine *storage_engine; /* storage engine plugin */
515
inline plugin::StorageEngine *db_type() const /* table_type for handler */
517
return storage_engine;
519
inline plugin::StorageEngine *getEngine() const /* table_type for handler */
521
return storage_engine;
524
TableIdentifier::Type tmp_table;
526
uint32_t ref_count; /* How many Table objects uses this */
527
uint32_t getTableCount()
533
uint32_t last_null_bit_pos;
534
uint32_t fields; /* Number of fields */
535
uint32_t rec_buff_length; /* Size of table->record[] buffer */
536
uint32_t keys, key_parts;
537
uint32_t max_key_length, max_unique_length, total_key_length;
538
uint32_t uniques; /* Number of UNIQUE index */
539
uint32_t null_fields; /* number of null fields */
540
uint32_t blob_fields; /* number of blob fields */
541
uint32_t timestamp_field_offset; /* Field number for timestamp field */
542
uint32_t varchar_fields; /* number of varchar fields */
543
uint32_t db_create_options; /* Create options from database */
544
uint32_t db_options_in_use; /* Options in use */
545
uint32_t db_record_offset; /* if HA_REC_IN_SEQ */
546
uint32_t rowid_field_offset; /* Field_nr +1 to rowid field */
550
* Currently the replication services component uses
551
* the primary_key member to determine which field is the table's
552
* primary key. However, as it exists, because this member is scalar, it
553
* only supports a single-column primary key. Is there a better way
554
* to ask for the fields which are in a primary key?
556
uint32_t primary_key;
557
/* Index of auto-updated TIMESTAMP field in field array */
558
uint32_t next_number_index; /* autoincrement key number */
559
uint32_t next_number_key_offset; /* autoinc keypart offset in a key */
560
uint32_t next_number_keypart; /* autoinc keypart number in a key */
561
uint32_t error, open_errno, errarg; /* error from open_table_def() */
562
uint32_t column_bitmap_size;
564
uint8_t blob_ptr_size; /* 4 or 8 */
565
bool db_low_byte_first; /* Portable row format */
568
bool isNameLock() const
573
bool replace_with_name_lock;
575
bool waiting_on_cond; /* Protection against free */
576
bool isWaitingOnCondition()
578
return waiting_on_cond;
582
Set of keys in use, implemented as a Bitmap.
583
Excludes keys disabled by ALTER Table ... DISABLE KEYS.
586
key_map keys_for_keyread;
589
event_observers is a class containing all the event plugins that have
590
registered an interest in this table.
593
plugin::EventObserverList *event_observers;
595
plugin::EventObserverList *getTableObservers()
597
return event_observers;
600
void setTableObservers(plugin::EventObserverList *observers)
602
event_observers= observers;
606
Set share's table cache key and update its db and table name appropriately.
609
set_table_cache_key()
610
key_buff Buffer with already built table cache key to be
611
referenced from share.
612
key_length Key length.
615
Since 'key_buff' buffer will be referenced from share it should has same
616
life-time as share itself.
617
This method automatically ensures that TableShare::table_name/db have
618
appropriate values by using table cache key as their source.
621
void set_table_cache_key(char *key_buff, uint32_t key_length, uint32_t db_length= 0, uint32_t table_name_length= 0)
623
table_cache_key.str= key_buff;
624
table_cache_key.length= key_length;
626
Let us use the fact that the key is "db/0/table_name/0" + optional
627
part for temporary tables.
629
db.str= table_cache_key.str;
630
db.length= db_length ? db_length : strlen(db.str);
631
table_name.str= db.str + db.length + 1;
632
table_name.length= table_name_length ? table_name_length :strlen(table_name.str);
635
inline bool honor_global_locks()
637
return (table_category == TABLE_CATEGORY_USER);
642
Initialize share for temporary tables
647
key Table_cache_key, as generated from create_table_def_key.
648
must start with db name.
649
key_length Length of key
650
table_name Table name
651
path Path to table (possible in lower case)
654
This is different from alloc_table_share() because temporary tables
655
don't have to be shared between threads or put into the table def
656
cache, so we can do some things notable simpler and faster
658
If table is not put in session->temporary_tables (happens only when
659
one uses OPEN TEMPORARY) then one can specify 'db' as key and
660
use key_length= 0 as neither table_cache_key or key_length will be used).
668
void init(const char *new_table_name,
669
const char *new_path)
671
init("", 0, new_table_name, new_path);
674
void init(const char *key,
675
uint32_t key_length, const char *new_table_name,
676
const char *new_path)
678
memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
679
table_category= TABLE_CATEGORY_TEMPORARY;
680
tmp_table= message::Table::INTERNAL;
682
db.length= strlen(key);
683
table_cache_key.str= (char*) key;
684
table_cache_key.length= key_length;
685
table_name.str= (char*) new_table_name;
686
table_name.length= strlen(new_table_name);
687
path.str= (char*) new_path;
688
normalized_path.str= (char*) new_path;
689
path.length= normalized_path.length= strlen(new_path);
694
void open_table_error(int pass_error, int db_errno, int pass_errarg);
697
Create a table cache key
701
key Create key here (must be of size MAX_DBKEY_LENGTH)
702
table_list Table definition
705
The table cache_key is created from:
709
if the table is a tmp table, we add the following to make each tmp table
712
4 bytes for master thread id
713
4 bytes pseudo thread id
718
static inline uint32_t createKey(char *key, const char *db_arg, const char *table_name_arg)
723
key_pos= strcpy(key_pos, db_arg) + strlen(db_arg);
724
key_pos= strcpy(key_pos+1, table_name_arg) +
725
strlen(table_name_arg);
726
key_length= (uint32_t)(key_pos-key)+1;
731
static inline uint32_t createKey(char *key, TableIdentifier &identifier)
736
key_pos= strcpy(key_pos, identifier.getSchemaName().c_str()) + identifier.getSchemaName().length();
737
key_pos= strcpy(key_pos + 1, identifier.getTableName().c_str()) + identifier.getTableName().length();
738
key_length= (uint32_t)(key_pos-key)+1;
743
static void cacheStart(void);
744
static void cacheStop(void);
745
static void release(TableShare *share);
746
static void release(const char *key, uint32_t key_length);
747
static TableDefinitionCache &getCache();
748
static TableShare *getShare(TableIdentifier &identifier);
749
static TableShare *getShare(Session *session,
750
char *key, uint32_t key_length, int *error);
752
friend std::ostream& operator<<(std::ostream& output, const TableShare &share)
754
output << "TableShare:(";
755
output << share.getSchemaName();
757
output << share.getTableName();
759
output << share.getTableTypeAsString();
761
output << share.getPath();
764
return output; // for multiple << operators.
769
Field *make_field(unsigned char *ptr,
770
uint32_t field_length,
772
unsigned char *null_pos,
773
unsigned char null_bit,
775
enum_field_types field_type,
776
const CHARSET_INFO * field_charset,
777
Field::utype unireg_check,
779
const char *field_name);
781
int open_table_def(Session& session, TableIdentifier &identifier);
783
int open_table_from_share(Session *session, const char *alias,
784
uint32_t db_stat, uint32_t ha_open_flags,
786
int parse_table_proto(Session& session, message::Table &table);
788
int inner_parse_table_proto(Session& session, message::Table &table);
791
} /* namespace drizzled */
793
#endif /* DRIZZLED_TABLE_SHARE_H */