~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_share.h

  • Committer: Monty Taylor
  • Date: 2010-10-02 05:07:25 UTC
  • mto: (1817.1.3 build)
  • mto: This revision was merged to the branch mainline in revision 1818.
  • Revision ID: mordred@inaugust.com-20101002050725-h1b30b0nr3leeoh1
Embed a modified version of parse_config_file. There are several more bugs
that we'll want to fix in it, and then submit upstream. Eventually we should
be able to remove this- but for now the version on lucid is completely
broken.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
 
29
29
#include <string>
30
30
 
 
31
#include <boost/unordered_map.hpp>
 
32
#include <boost/thread/condition_variable.hpp>
 
33
 
31
34
#include "drizzled/typelib.h"
32
 
#include "drizzled/my_hash.h"
33
35
#include "drizzled/memory/root.h"
34
36
#include "drizzled/message/table.pb.h"
 
37
#include "drizzled/util/string.h"
35
38
 
36
39
namespace drizzled
37
40
{
38
41
 
 
42
typedef boost::unordered_map< TableIdentifier::Key, TableShare *> TableDefinitionCache;
 
43
 
 
44
const static std::string STANDARD_STRING("STANDARD");
 
45
const static std::string TEMPORARY_STRING("TEMPORARY");
 
46
const static std::string INTERNAL_STRING("INTERNAL");
 
47
const static std::string FUNCTION_STRING("FUNCTION");
 
48
 
 
49
namespace plugin
 
50
{
 
51
class EventObserverList;
 
52
}
 
53
 
 
54
class Field_blob;
 
55
 
39
56
class TableShare
40
57
{
 
58
  typedef std::vector<std::string> StringVector;
41
59
public:
42
 
  TableShare() :
43
 
    table_category(TABLE_UNKNOWN_CATEGORY),
44
 
    open_count(0),
45
 
    field(NULL),
46
 
    found_next_number_field(NULL),
47
 
    timestamp_field(NULL),
48
 
    key_info(NULL),
49
 
    blob_field(NULL),
50
 
    intervals(NULL),
51
 
    default_values(NULL),
52
 
    block_size(0),
53
 
    version(0),
54
 
    timestamp_offset(0),
55
 
    reclength(0),
56
 
    stored_rec_length(0),
57
 
    row_type(ROW_TYPE_DEFAULT),
58
 
    max_rows(0),
59
 
    table_proto(NULL),
60
 
    storage_engine(NULL),
61
 
    tmp_table(NO_TMP_TABLE),
62
 
    ref_count(0),
63
 
    null_bytes(0),
64
 
    last_null_bit_pos(0),
65
 
    fields(0),
66
 
    rec_buff_length(0),
67
 
    keys(0),
68
 
    key_parts(0),
69
 
    max_key_length(0),
70
 
    max_unique_length(0),
71
 
    total_key_length(0),
72
 
    uniques(0),
73
 
    null_fields(0),
74
 
    blob_fields(0),
75
 
    timestamp_field_offset(0),
76
 
    varchar_fields(0),
77
 
    db_create_options(0),
78
 
    db_options_in_use(0),
79
 
    db_record_offset(0),
80
 
    rowid_field_offset(0),
81
 
    primary_key(0),
82
 
    next_number_index(0),
83
 
    next_number_key_offset(0),
84
 
    next_number_keypart(0),
85
 
    error(0),
86
 
    open_errno(0),
87
 
    errarg(0),
88
 
    column_bitmap_size(0),
89
 
    blob_ptr_size(0),
90
 
    db_low_byte_first(false),
91
 
    name_lock(false),
92
 
    replace_with_name_lock(false),
93
 
    waiting_on_cond(false),
94
 
    keys_in_use(0),
95
 
    keys_for_keyread(0)
96
 
  {
97
 
    init();
98
 
  }
99
 
 
100
 
  TableShare(const char *key,
101
 
             uint32_t key_length,
102
 
             const char *new_table_name,
103
 
             const char *new_path) :
104
 
    table_category(TABLE_UNKNOWN_CATEGORY),
105
 
    open_count(0),
106
 
    field(NULL),
107
 
    found_next_number_field(NULL),
108
 
    timestamp_field(NULL),
109
 
    key_info(NULL),
110
 
    blob_field(NULL),
111
 
    intervals(NULL),
112
 
    default_values(NULL),
113
 
    block_size(0),
114
 
    version(0),
115
 
    timestamp_offset(0),
116
 
    reclength(0),
117
 
    stored_rec_length(0),
118
 
    row_type(ROW_TYPE_DEFAULT),
119
 
    max_rows(0),
120
 
    table_proto(NULL),
121
 
    storage_engine(NULL),
122
 
    tmp_table(NO_TMP_TABLE),
123
 
    ref_count(0),
124
 
    null_bytes(0),
125
 
    last_null_bit_pos(0),
126
 
    fields(0),
127
 
    rec_buff_length(0),
128
 
    keys(0),
129
 
    key_parts(0),
130
 
    max_key_length(0),
131
 
    max_unique_length(0),
132
 
    total_key_length(0),
133
 
    uniques(0),
134
 
    null_fields(0),
135
 
    blob_fields(0),
136
 
    timestamp_field_offset(0),
137
 
    varchar_fields(0),
138
 
    db_create_options(0),
139
 
    db_options_in_use(0),
140
 
    db_record_offset(0),
141
 
    rowid_field_offset(0),
142
 
    primary_key(0),
143
 
    next_number_index(0),
144
 
    next_number_key_offset(0),
145
 
    next_number_keypart(0),
146
 
    error(0),
147
 
    open_errno(0),
148
 
    errarg(0),
149
 
    column_bitmap_size(0),
150
 
    blob_ptr_size(0),
151
 
    db_low_byte_first(false),
152
 
    name_lock(false),
153
 
    replace_with_name_lock(false),
154
 
    waiting_on_cond(false),
155
 
    keys_in_use(0),
156
 
    keys_for_keyread(0)
157
 
  {
158
 
    init(key, key_length, new_table_name, new_path);
159
 
  }
160
 
 
 
60
  TableShare(TableIdentifier::Type type_arg);
 
61
 
 
62
  TableShare(TableIdentifier &identifier, const TableIdentifier::Key &key); // Used by placeholder
 
63
 
 
64
  TableShare(const TableIdentifier &identifier); // Just used during createTable()
 
65
 
 
66
  TableShare(TableIdentifier::Type type_arg,
 
67
             TableIdentifier &identifier,
 
68
             char *path_arg= NULL, uint32_t path_length_arg= 0); // Shares for cache
 
69
 
 
70
  ~TableShare();
 
71
 
 
72
private:
161
73
  /** Category of this table. */
162
74
  enum_table_category table_category;
163
75
 
164
76
  uint32_t open_count;                  /* Number of tables in open list */
 
77
public:
 
78
 
 
79
  bool isTemporaryCategory() const
 
80
  {
 
81
    return (table_category == TABLE_CATEGORY_TEMPORARY);
 
82
  }
 
83
 
 
84
  void setTableCategory(enum_table_category arg)
 
85
  {
 
86
    table_category= arg;
 
87
  }
165
88
 
166
89
  /* The following is copied to each Table on OPEN */
167
 
  Field **field;
 
90
  typedef std::vector<Field *> Fields;
 
91
private:
 
92
  Fields field;
 
93
public:
 
94
  const Fields getFields() const
 
95
  {
 
96
    return field;
 
97
  }
 
98
 
 
99
  Field ** getFields(bool)
 
100
  {
 
101
    return &field[0];
 
102
  }
 
103
 
 
104
  void setFields(uint32_t arg)
 
105
  {
 
106
    field.resize(arg);
 
107
  }
 
108
 
 
109
  uint32_t positionFields(Field **arg) const
 
110
  {
 
111
    return (arg - (Field **)&field[0]);
 
112
  }
 
113
 
 
114
  void pushField(Field *arg)
 
115
  {
 
116
    fields++;
 
117
    field.push_back(arg);
 
118
  }
 
119
 
 
120
 
168
121
  Field **found_next_number_field;
 
122
private:
169
123
  Field *timestamp_field;               /* Used only during open */
170
 
  KEY  *key_info;                       /* data of keys in database */
171
 
  uint  *blob_field;                    /* Index to blobs in Field arrray*/
 
124
public:
 
125
 
 
126
  Field *getTimestampField() const               /* Used only during open */
 
127
  {
 
128
    return timestamp_field;
 
129
  }
 
130
 
 
131
  void setTimestampField(Field *arg) /* Used only during open */
 
132
  {
 
133
    timestamp_field= arg;
 
134
  }
 
135
 
 
136
 
 
137
private:
 
138
  KeyInfo  *key_info;                   /* data of keys in database */
 
139
public:
 
140
  KeyInfo &getKeyInfo(uint32_t arg) const
 
141
  {
 
142
    return key_info[arg];
 
143
  }
 
144
  std::vector<uint>     blob_field;                     /* Index to blobs in Field arrray*/
172
145
 
173
146
  /* hash of field names (contains pointers to elements of field array) */
174
 
  HASH  name_hash;                      /* hash of field names */
 
147
private:
 
148
  typedef boost::unordered_map < std::string, Field **, util::insensitive_hash, util::insensitive_equal_to> FieldMap;
 
149
  typedef std::pair< std::string, Field ** > FieldMapPair;
 
150
  FieldMap name_hash; /* hash of field names */
 
151
public:
 
152
  size_t getNamedFieldSize() const
 
153
  {
 
154
    return name_hash.size();
 
155
  }
 
156
 
 
157
  Field **getNamedField(const std::string &arg)
 
158
  {
 
159
    FieldMap::iterator iter= name_hash.find(arg);
 
160
 
 
161
    if (iter == name_hash.end())
 
162
        return 0;
 
163
 
 
164
    return (*iter).second;
 
165
  }
 
166
 
 
167
private:
175
168
  memory::Root mem_root;
176
 
  TYPELIB keynames;                     /* Pointers to keynames */
177
 
  TYPELIB fieldnames;                   /* Pointer to fieldnames */
178
 
  TYPELIB *intervals;                   /* pointer to interval info */
179
 
  pthread_mutex_t mutex;                /* For locking the share  */
180
 
  pthread_cond_t cond;                  /* To signal that share is ready */
181
 
 
182
 
  unsigned char *default_values;                /* row with default values */
 
169
public:
 
170
  void *alloc_root(size_t arg)
 
171
  {
 
172
    return mem_root.alloc_root(arg);
 
173
  }
 
174
 
 
175
  char *strmake_root(const char *str_arg, size_t len_arg)
 
176
  {
 
177
    return mem_root.strmake_root(str_arg, len_arg);
 
178
  }
 
179
 
 
180
  memory::Root *getMemRoot()
 
181
  {
 
182
    return &mem_root;
 
183
  }
 
184
 
 
185
private:
 
186
  std::vector<std::string> _keynames;
 
187
 
 
188
  void addKeyName(std::string arg)
 
189
  {
 
190
    std::transform(arg.begin(), arg.end(),
 
191
                   arg.begin(), ::toupper);
 
192
    _keynames.push_back(arg);
 
193
  }
 
194
public:
 
195
  bool doesKeyNameExist(const char *name_arg, uint32_t name_length, uint32_t &position) const
 
196
  {
 
197
    std::string arg(name_arg, name_length);
 
198
    std::transform(arg.begin(), arg.end(),
 
199
                   arg.begin(), ::toupper);
 
200
 
 
201
    std::vector<std::string>::const_iterator iter= std::find(_keynames.begin(), _keynames.end(), arg);
 
202
 
 
203
    if (iter == _keynames.end())
 
204
      return false;
 
205
 
 
206
    position= iter -  _keynames.begin();
 
207
 
 
208
    return true;
 
209
  }
 
210
 
 
211
  bool doesKeyNameExist(std::string arg, uint32_t &position) const
 
212
  {
 
213
    std::transform(arg.begin(), arg.end(),
 
214
                   arg.begin(), ::toupper);
 
215
 
 
216
    std::vector<std::string>::const_iterator iter= std::find(_keynames.begin(), _keynames.end(), arg);
 
217
 
 
218
    if (iter == _keynames.end())
 
219
    {
 
220
      position= -1; //historical, required for finding primary key from unique
 
221
      return false;
 
222
    }
 
223
 
 
224
    position= iter -  _keynames.begin();
 
225
 
 
226
    return true;
 
227
  }
 
228
 
 
229
private:
 
230
  std::vector<TYPELIB> intervals;                       /* pointer to interval info */
 
231
 
 
232
  boost::mutex mutex;                /* For locking the share  */
 
233
  boost::condition_variable cond;                       /* To signal that share is ready */
 
234
 
 
235
 
 
236
  void lock()
 
237
  {
 
238
    mutex.lock();
 
239
  }
 
240
 
 
241
  void unlock()
 
242
  {
 
243
    mutex.unlock();
 
244
  }
 
245
public:
 
246
 
 
247
private:
 
248
  std::vector<unsigned char> default_values;            /* row with default values */
 
249
public:
 
250
  unsigned char * getDefaultValues()
 
251
  {
 
252
    return &default_values[0];
 
253
  }
 
254
  void resizeDefaultValues(size_t arg)
 
255
  {
 
256
    default_values.resize(arg);
 
257
  }
 
258
 
183
259
  const CHARSET_INFO *table_charset; /* Default charset of string fields */
184
260
 
185
261
  MyBitmap all_set;
 
262
private:
 
263
  std::vector<my_bitmap_map> all_bitmap;
 
264
 
 
265
public:
186
266
  /*
187
267
    Key which is used for looking-up table in table cache and in the list
188
268
    of thread's temporary tables. Has the form of:
193
273
    should correspond to each other.
194
274
    To ensure this one can use set_table_cache() methods.
195
275
  */
196
 
  LEX_STRING table_cache_key;
 
276
private:
 
277
  TableIdentifier::Key private_key_for_cache; // This will not exist in the final design.
 
278
  std::vector<char> private_normalized_path; // This will not exist in the final design.
197
279
  LEX_STRING db;                        /* Pointer to db */
198
280
  LEX_STRING table_name;                /* Table name (for open) */
199
281
  LEX_STRING path;      /* Path to table (from datadir) */
200
282
  LEX_STRING normalized_path;           /* unpack_filename(path) */
 
283
public:
 
284
 
 
285
  const char *getNormalizedPath() const
 
286
  {
 
287
    return normalized_path.str;
 
288
  }
 
289
 
 
290
  const char *getPath() const
 
291
  {
 
292
    return path.str;
 
293
  }
 
294
 
 
295
  const TableIdentifier::Key& getCacheKey() const // This should never be called when we aren't looking at a cache.
 
296
  {
 
297
    assert(private_key_for_cache.size());
 
298
    return private_key_for_cache;
 
299
  }
 
300
 
 
301
  size_t getCacheKeySize() const
 
302
  {
 
303
    return private_key_for_cache.size();
 
304
  }
 
305
 
 
306
  void setPath(char *str_arg, uint32_t size_arg)
 
307
  {
 
308
    path.str= str_arg;
 
309
    path.length= size_arg;
 
310
  }
 
311
 
 
312
  void setNormalizedPath(char *str_arg, uint32_t size_arg)
 
313
  {
 
314
    normalized_path.str= str_arg;
 
315
    normalized_path.length= size_arg;
 
316
  }
 
317
 
 
318
  const char *getTableName() const
 
319
  {
 
320
    return table_name.str;
 
321
  }
 
322
 
 
323
  uint32_t getTableNameSize() const
 
324
  {
 
325
    return table_name.length;
 
326
  }
 
327
 
 
328
  const std::string &getTableName(std::string &name_arg) const
 
329
  {
 
330
    name_arg.clear();
 
331
    name_arg.append(table_name.str, table_name.length);
 
332
 
 
333
    return name_arg;
 
334
  }
 
335
 
 
336
  const char *getSchemaName() const
 
337
  {
 
338
    return db.str;
 
339
  }
 
340
 
 
341
  const std::string &getSchemaName(std::string &schema_name_arg) const
 
342
  {
 
343
    schema_name_arg.clear();
 
344
    schema_name_arg.append(db.str, db.length);
 
345
 
 
346
    return schema_name_arg;
 
347
  }
201
348
 
202
349
  uint32_t   block_size;                   /* create information */
 
350
 
 
351
private:
203
352
  uint64_t   version;
 
353
public:
 
354
  uint64_t getVersion() const
 
355
  {
 
356
    return version;
 
357
  }
 
358
 
 
359
  void refreshVersion()
 
360
  {
 
361
   version= refresh_version;
 
362
  }
 
363
 
 
364
  void resetVersion()
 
365
  {
 
366
    version= 0;
 
367
  }
 
368
 
204
369
  uint32_t   timestamp_offset;          /* Set to offset+1 of record */
 
370
private:
205
371
  uint32_t   reclength;                 /* Recordlength */
 
372
public:
206
373
  uint32_t   stored_rec_length;         /* Stored record length*/
207
 
  enum row_type row_type;               /* How rows are stored */
 
374
 
 
375
  uint32_t getRecordLength() const
 
376
  {
 
377
    return reclength;
 
378
  }
 
379
 
 
380
  void setRecordLength(uint32_t arg)
 
381
  {
 
382
    reclength= arg;
 
383
  }
 
384
 
 
385
  const Field_blob *getBlobFieldAt(uint32_t arg) const
 
386
  {
 
387
    if (arg < blob_fields)
 
388
      return (Field_blob*) field[blob_field[arg]];
 
389
 
 
390
    return NULL;
 
391
  }
208
392
 
209
393
private:
210
394
  /* Max rows is a hint to HEAP during a create tmp table */
213
397
  message::Table *table_proto;
214
398
public:
215
399
 
 
400
  /*
 
401
    @note Without a table_proto, we assume we are building a STANDARD table.
 
402
    This will be modified once we use Identifiers in the Share itself.
 
403
  */
 
404
  message::Table::TableType getTableType() const
 
405
  {
 
406
    return table_proto ? table_proto->type() : message::Table::STANDARD;
 
407
  }
 
408
 
 
409
  const std::string &getTableTypeAsString() const
 
410
  {
 
411
    switch (table_proto->type())
 
412
    {
 
413
    default:
 
414
    case message::Table::STANDARD:
 
415
      return STANDARD_STRING;
 
416
    case message::Table::TEMPORARY:
 
417
      return TEMPORARY_STRING;
 
418
    case message::Table::INTERNAL:
 
419
      return INTERNAL_STRING;
 
420
    case message::Table::FUNCTION:
 
421
      return FUNCTION_STRING;
 
422
    }
 
423
  }
 
424
 
216
425
  /* This is only used in one location currently */
 
426
  inline message::Table *getTableProto() const
 
427
  {
 
428
    return table_proto;
 
429
  }
 
430
 
217
431
  inline void setTableProto(message::Table *arg)
218
432
  {
219
433
    assert(table_proto == NULL);
220
434
    table_proto= arg;
221
435
  }
222
436
 
223
 
  inline bool hasComment()
 
437
  inline bool hasComment() const
224
438
  {
225
439
    return (table_proto) ?  table_proto->options().has_comment() : false; 
226
440
  }
230
444
    return (table_proto && table_proto->has_options()) ?  table_proto->options().comment().c_str() : NULL; 
231
445
  }
232
446
 
233
 
  inline uint32_t getCommentLength()
 
447
  inline uint32_t getCommentLength() const
234
448
  {
235
449
    return (table_proto) ? table_proto->options().comment().length() : 0; 
236
450
  }
237
451
 
238
 
  inline bool hasKeyBlockSize()
239
 
  {
240
 
    return (table_proto) ? table_proto->options().has_key_block_size() : false;
241
 
  }
242
 
 
243
 
  inline uint32_t getKeyBlockSize()
244
 
  {
245
 
    return (table_proto) ? table_proto->options().key_block_size() : 0;
246
 
  }
247
 
 
248
 
  inline uint64_t getMaxRows()
 
452
  inline uint64_t getMaxRows() const
249
453
  {
250
454
    return max_rows;
251
455
  }
255
459
    max_rows= arg;
256
460
  }
257
461
 
 
462
  /**
 
463
   * Returns true if the supplied Field object
 
464
   * is part of the table's primary key.
 
465
 */
 
466
  bool fieldInPrimaryKey(Field *field) const;
 
467
 
258
468
  plugin::StorageEngine *storage_engine;                        /* storage engine plugin */
259
469
  inline plugin::StorageEngine *db_type() const /* table_type for handler */
260
470
  {
264
474
  {
265
475
    return storage_engine;
266
476
  }
267
 
  enum tmp_table_type tmp_table;
268
 
 
 
477
 
 
478
private:
 
479
  TableIdentifier::Type tmp_table;
 
480
public:
 
481
 
 
482
  TableIdentifier::Type getType() const
 
483
  {
 
484
    return tmp_table;
 
485
  }
 
486
 
 
487
private:
269
488
  uint32_t ref_count;       /* How many Table objects uses this */
 
489
public:
 
490
  uint32_t getTableCount() const
 
491
  {
 
492
    return ref_count;
 
493
  }
 
494
 
 
495
  void incrementTableCount()
 
496
  {
 
497
    lock();
 
498
    ref_count++;
 
499
    unlock();
 
500
  }
 
501
 
270
502
  uint32_t null_bytes;
271
503
  uint32_t last_null_bit_pos;
272
504
  uint32_t fields;                              /* Number of fields */
 
505
 
 
506
  uint32_t sizeFields() const
 
507
  {
 
508
    return fields;
 
509
  }
 
510
 
273
511
  uint32_t rec_buff_length;                 /* Size of table->record[] buffer */
274
 
  uint32_t keys, key_parts;
 
512
  uint32_t keys;
 
513
 
 
514
  uint32_t sizeKeys() const
 
515
  {
 
516
    return keys;
 
517
  }
 
518
  uint32_t key_parts;
275
519
  uint32_t max_key_length, max_unique_length, total_key_length;
276
520
  uint32_t uniques;                         /* Number of UNIQUE index */
277
521
  uint32_t null_fields;                 /* number of null fields */
290
534
   * primary key.  However, as it exists, because this member is scalar, it
291
535
   * only supports a single-column primary key. Is there a better way
292
536
   * to ask for the fields which are in a primary key?
293
 
   */
 
537
 */
 
538
private:
294
539
  uint32_t primary_key;
 
540
public:
 
541
 
 
542
  uint32_t getPrimaryKey() const
 
543
  {
 
544
    return primary_key;
 
545
  }
 
546
 
 
547
  bool hasPrimaryKey() const
 
548
  {
 
549
    return primary_key != MAX_KEY;
 
550
  }
 
551
 
295
552
  /* Index of auto-updated TIMESTAMP field in field array */
296
553
  uint32_t next_number_index;               /* autoincrement key number */
297
554
  uint32_t next_number_key_offset;          /* autoinc keypart offset in a key */
301
558
 
302
559
  uint8_t blob_ptr_size;                        /* 4 or 8 */
303
560
  bool db_low_byte_first;               /* Portable row format */
 
561
 
 
562
private:
304
563
  bool name_lock;
 
564
public:
 
565
  bool isNameLock() const
 
566
  {
 
567
    return name_lock;
 
568
  }
 
569
 
305
570
  bool replace_with_name_lock;
 
571
 
 
572
private:
306
573
  bool waiting_on_cond;                 /* Protection against free */
 
574
public:
 
575
  bool isWaitingOnCondition()
 
576
  {
 
577
    return waiting_on_cond;
 
578
  }
307
579
 
308
580
  /*
309
581
    Set of keys in use, implemented as a Bitmap.
312
584
  key_map keys_in_use;
313
585
  key_map keys_for_keyread;
314
586
 
 
587
  /* 
 
588
    event_observers is a class containing all the event plugins that have 
 
589
    registered an interest in this table.
 
590
  */
 
591
  private:
 
592
  plugin::EventObserverList *event_observers;
 
593
  public:
 
594
  plugin::EventObserverList *getTableObservers() 
 
595
  { 
 
596
    return event_observers;
 
597
  }
 
598
  
 
599
  void setTableObservers(plugin::EventObserverList *observers) 
 
600
  { 
 
601
    event_observers= observers;
 
602
  }
 
603
  
315
604
  /*
316
 
    Set share's table cache key and update its db and table name appropriately.
 
605
    Set share's identifier information.
317
606
 
318
607
    SYNOPSIS
319
 
    set_table_cache_key()
320
 
    key_buff    Buffer with already built table cache key to be
321
 
    referenced from share.
322
 
    key_length  Key length.
 
608
    setIdentifier()
323
609
 
324
610
    NOTES
325
 
    Since 'key_buff' buffer will be referenced from share it should has same
326
 
    life-time as share itself.
327
 
    This method automatically ensures that TableShare::table_name/db have
328
 
    appropriate values by using table cache key as their source.
329
 
  */
330
 
 
331
 
  void set_table_cache_key(char *key_buff, uint32_t key_length)
332
 
  {
333
 
    table_cache_key.str= key_buff;
334
 
    table_cache_key.length= key_length;
335
 
    /*
336
 
      Let us use the fact that the key is "db/0/table_name/0" + optional
337
 
      part for temporary tables.
338
 
    */
339
 
    db.str=            table_cache_key.str;
340
 
    db.length=         strlen(db.str);
341
 
    table_name.str=    db.str + db.length + 1;
342
 
    table_name.length= strlen(table_name.str);
343
 
  }
344
 
 
345
 
 
346
 
  /*
347
 
    Set share's table cache key and update its db and table name appropriately.
348
 
 
349
 
    SYNOPSIS
350
 
    set_table_cache_key()
351
 
    key_buff    Buffer to be used as storage for table cache key
352
 
    (should be at least key_length bytes).
353
 
    key         Value for table cache key.
354
 
    key_length  Key length.
355
 
 
356
 
    NOTE
357
 
    Since 'key_buff' buffer will be used as storage for table cache key
358
 
    it should has same life-time as share itself.
359
 
  */
360
 
 
361
 
  void set_table_cache_key(char *key_buff, const char *key, uint32_t key_length)
362
 
  {
363
 
    memcpy(key_buff, key, key_length);
364
 
    set_table_cache_key(key_buff, key_length);
365
 
  }
 
611
  */
 
612
 
 
613
  void setIdentifier(TableIdentifier &identifier_arg);
366
614
 
367
615
  inline bool honor_global_locks()
368
616
  {
383
631
    path        Path to table (possible in lower case)
384
632
 
385
633
    NOTES
386
 
    This is different from alloc_table_share() because temporary tables
387
 
    don't have to be shared between threads or put into the table def
388
 
    cache, so we can do some things notable simpler and faster
389
 
 
390
 
    If table is not put in session->temporary_tables (happens only when
391
 
    one uses OPEN TEMPORARY) then one can specify 'db' as key and
392
 
    use key_length= 0 as neither table_cache_key or key_length will be used).
 
634
    
393
635
  */
394
636
 
395
 
  void init()
396
 
  {
397
 
    init("", 0, "", "");
398
 
  }
399
 
 
 
637
private:
400
638
  void init(const char *new_table_name,
401
 
            const char *new_path)
402
 
  {
403
 
    init("", 0, new_table_name, new_path);
404
 
  }
405
 
 
406
 
  void init(const char *key,
407
 
            uint32_t key_length, const char *new_table_name,
408
 
            const char *new_path)
409
 
  {
410
 
    memset(this, 0, sizeof(TableShare));
411
 
    memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
412
 
    table_category=         TABLE_CATEGORY_TEMPORARY;
413
 
    tmp_table=              INTERNAL_TMP_TABLE;
414
 
    db.str=                 (char*) key;
415
 
    db.length=           strlen(key);
416
 
    table_cache_key.str=    (char*) key;
417
 
    table_cache_key.length= key_length;
418
 
    table_name.str=         (char*) new_table_name;
419
 
    table_name.length=      strlen(new_table_name);
420
 
    path.str=               (char*) new_path;
421
 
    normalized_path.str=    (char*) new_path;
422
 
    path.length= normalized_path.length= strlen(new_path);
423
 
 
424
 
    return;
425
 
  }
426
 
 
427
 
  /*
428
 
    Free table share and memory used by it
429
 
 
430
 
    SYNOPSIS
431
 
    free_table_share()
432
 
    share               Table share
433
 
 
434
 
    NOTES
435
 
    share->mutex must be locked when we come here if it's not a temp table
436
 
  */
437
 
 
438
 
  void free_table_share()
439
 
  {
440
 
    memory::Root new_mem_root;
441
 
    assert(ref_count == 0);
442
 
 
443
 
    /*
444
 
      If someone is waiting for this to be deleted, inform it about this.
445
 
      Don't do a delete until we know that no one is refering to this anymore.
446
 
    */
447
 
    if (tmp_table == NO_TMP_TABLE)
448
 
    {
449
 
      /* share->mutex is locked in release_table_share() */
450
 
      while (waiting_on_cond)
451
 
      {
452
 
        pthread_cond_broadcast(&cond);
453
 
        pthread_cond_wait(&cond, &mutex);
454
 
      }
455
 
      /* No thread refers to this anymore */
456
 
      pthread_mutex_unlock(&mutex);
457
 
      pthread_mutex_destroy(&mutex);
458
 
      pthread_cond_destroy(&cond);
459
 
    }
460
 
    hash_free(&name_hash);
461
 
 
462
 
    storage_engine= NULL;
463
 
 
464
 
    delete table_proto;
465
 
    table_proto= NULL;
466
 
 
467
 
    /* We must copy mem_root from share because share is allocated through it */
468
 
    memcpy(&new_mem_root, &mem_root, sizeof(new_mem_root));
469
 
    free_root(&new_mem_root, MYF(0));                 // Free's share
470
 
  }
 
639
            const char *new_path);
 
640
public:
471
641
 
472
642
  void open_table_error(int pass_error, int db_errno, int pass_errarg);
473
643
 
474
 
 
475
 
 
476
 
  /*
477
 
    Create a table cache key
478
 
 
479
 
    SYNOPSIS
480
 
    createKey()
481
 
    key                 Create key here (must be of size MAX_DBKEY_LENGTH)
482
 
    table_list          Table definition
483
 
 
484
 
    IMPLEMENTATION
485
 
    The table cache_key is created from:
486
 
    db_name + \0
487
 
    table_name + \0
488
 
 
489
 
    if the table is a tmp table, we add the following to make each tmp table
490
 
    unique on the slave:
491
 
 
492
 
    4 bytes for master thread id
493
 
    4 bytes pseudo thread id
494
 
 
495
 
    RETURN
496
 
    Length of key
497
 
  */
498
 
 
499
 
  static inline uint32_t createKey(char *key, std::string& db_arg,
500
 
                                   std::string& table_name_arg)
501
 
  {
502
 
    return createKey(key, db_arg.c_str(), table_name_arg.c_str());
503
 
  }
504
 
 
505
 
  static inline uint32_t createKey(char *key, const char *db_arg, const char *table_name_arg)
506
 
  {
507
 
    uint32_t key_length;
508
 
    char *key_pos= key;
509
 
 
510
 
    key_pos= strcpy(key_pos, db_arg) + strlen(db_arg);
511
 
    key_pos= strcpy(key_pos+1, table_name_arg) +
512
 
      strlen(table_name_arg);
513
 
    key_length= (uint32_t)(key_pos-key)+1;
514
 
 
515
 
    return key_length;
516
 
  }
517
 
 
518
644
  static void cacheStart(void);
519
 
  static void cacheStop(void);
520
645
  static void release(TableShare *share);
521
 
  static void release(const char *key, uint32_t key_length);
522
 
  static TableShare *getShare(const char *db, const char *table_name);
523
 
  static TableShare *getShare(Session *session, 
524
 
                              TableList *table_list, char *key,
525
 
                              uint32_t key_length, uint32_t, int *error);
 
646
  static void release(TableIdentifier &identifier);
 
647
  static const TableDefinitionCache &getCache();
 
648
  static TableShare *getShare(TableIdentifier &identifier);
 
649
  static TableShare *getShareCreate(Session *session, 
 
650
                                    TableIdentifier &identifier,
 
651
                                    int *error);
 
652
 
 
653
  friend std::ostream& operator<<(std::ostream& output, const TableShare &share)
 
654
  {
 
655
    output << "TableShare:(";
 
656
    output <<  share.getSchemaName();
 
657
    output << ", ";
 
658
    output << share.getTableName();
 
659
    output << ", ";
 
660
    output << share.getTableTypeAsString();
 
661
    output << ", ";
 
662
    output << share.getPath();
 
663
    output << ")";
 
664
 
 
665
    return output;  // for multiple << operators.
 
666
  }
 
667
 
 
668
  Field *make_field(unsigned char *ptr,
 
669
                    uint32_t field_length,
 
670
                    bool is_nullable,
 
671
                    unsigned char *null_pos,
 
672
                    unsigned char null_bit,
 
673
                    uint8_t decimals,
 
674
                    enum_field_types field_type,
 
675
                    const CHARSET_INFO * field_charset,
 
676
                    Field::utype unireg_check,
 
677
                    TYPELIB *interval,
 
678
                    const char *field_name);
 
679
 
 
680
  int open_table_def(Session& session, TableIdentifier &identifier);
 
681
 
 
682
  int open_table_from_share(Session *session,
 
683
                            const TableIdentifier &identifier,
 
684
                            const char *alias,
 
685
                            uint32_t db_stat, uint32_t ha_open_flags,
 
686
                            Table &outparam);
 
687
  int parse_table_proto(Session& session, message::Table &table);
 
688
private:
 
689
  int inner_parse_table_proto(Session& session, message::Table &table);
526
690
};
527
691
 
528
692
} /* namespace drizzled */