~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_share.h

  • Committer: Padraig O'Sullivan
  • Date: 2009-08-26 04:24:02 UTC
  • mto: This revision was merged to the branch mainline in revision 1139.
  • Revision ID: osullivan.padraig@gmail.com-20090826042402-ryh95r58b7godtbj
Made all data members of the KeyField class private and provided accessors
when necessary.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2009 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2009 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
23
23
  instance of table share per one table in the database.
24
24
*/
25
25
 
26
 
#ifndef DRIZZLED_TABLE_INSTANCE_BASE_H
27
 
#define DRIZZLED_TABLE_INSTANCE_BASE_H
28
 
 
29
26
#include <string>
30
27
 
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>
36
 
 
37
 
#include "drizzled/typelib.h"
38
 
#include "drizzled/memory/root.h"
39
 
#include "drizzled/message.h"
40
 
#include "drizzled/util/string.h"
41
 
 
42
 
#include "drizzled/lex_string.h"
43
 
#include "drizzled/key_map.h"
44
 
 
45
 
#include "drizzled/table/cache.h"
46
 
 
47
 
#include <drizzled/field.h>
48
 
 
49
 
 
50
 
namespace drizzled
51
 
{
52
 
 
53
 
const static std::string NO_PROTOBUFFER_AVAILABLE("NO PROTOBUFFER AVAILABLE");
54
 
 
55
 
namespace plugin
56
 
{
57
 
class EventObserverList;
58
 
class StorageEngine;
59
 
}
60
 
 
61
 
namespace table {
62
 
class Singular;
63
 
}
64
 
 
65
 
class Field_blob;
66
28
 
67
29
class TableShare
68
30
{
69
 
  typedef std::vector<std::string> StringVector;
70
 
 
71
31
public:
72
 
  typedef boost::shared_ptr<TableShare> shared_ptr;
73
 
  typedef std::vector <shared_ptr> vector;
74
 
 
75
 
  TableShare(const identifier::Table::Type type_arg);
76
 
 
77
 
  TableShare(const identifier::Table &identifier, const identifier::Table::Key &key); // Used by placeholder
78
 
 
79
 
  TableShare(const identifier::Table &identifier); // Just used during createTable()
80
 
 
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
84
 
 
85
 
  virtual ~TableShare();
86
 
 
87
 
private:
 
32
  TableShare() 
 
33
  {
 
34
    init();
 
35
  }                    /* Remove gcc warning */
 
36
 
 
37
  TableShare(const char *key,
 
38
             uint32_t key_length, const char *new_table_name,
 
39
             const char *new_path)
 
40
  {
 
41
    init(key, key_length, new_table_name, new_path);
 
42
  }
 
43
 
88
44
  /** Category of this table. */
89
45
  enum_table_category table_category;
90
46
 
91
 
public:
92
 
  bool isTemporaryCategory() const
93
 
  {
94
 
    return (table_category == TABLE_CATEGORY_TEMPORARY);
95
 
  }
96
 
 
97
 
  void setTableCategory(enum_table_category arg)
98
 
  {
99
 
    table_category= arg;
100
 
  }
 
47
  uint32_t open_count;                  /* Number of tables in open list */
101
48
 
102
49
  /* The following is copied to each Table on OPEN */
103
 
  typedef std::vector<Field *> Fields;
104
 
 
105
 
private:
106
 
  Fields _fields;
107
 
 
108
 
public:
109
 
  const Fields getFields() const
110
 
  {
111
 
    return _fields;
112
 
  }
113
 
 
114
 
  Fields getFields()
115
 
  {
116
 
    return _fields;
117
 
  }
118
 
 
119
 
  Field ** getFields(bool)
120
 
  {
121
 
    return &_fields[0];
122
 
  }
123
 
 
124
 
  void setFields(uint32_t arg)
125
 
  {
126
 
    _fields.resize(arg);
127
 
  }
128
 
 
129
 
  uint32_t positionFields(Field **arg) const
130
 
  {
131
 
    return (arg - (Field **)&_fields[0]);
132
 
  }
133
 
 
134
 
  void pushField(Field *arg)
135
 
  {
136
 
    _field_size++;
137
 
    _fields.push_back(arg);
138
 
  }
139
 
 
 
50
  Field **field;
140
51
  Field **found_next_number_field;
141
 
 
142
 
private:
143
52
  Field *timestamp_field;               /* Used only during open */
144
 
 
145
 
public:
146
 
 
147
 
  Field *getTimestampField() const               /* Used only during open */
148
 
  {
149
 
    return timestamp_field;
150
 
  }
151
 
 
152
 
  void setTimestampField(Field *arg) /* Used only during open */
153
 
  {
154
 
    timestamp_field= arg;
155
 
  }
156
 
 
157
 
 
158
 
private:
159
 
  KeyInfo  *key_info;                   /* data of keys in database */
160
 
 
161
 
public:
162
 
  KeyInfo &getKeyInfo(uint32_t arg) const
163
 
  {
164
 
    return key_info[arg];
165
 
  }
166
 
  std::vector<uint>     blob_field;                     /* Index to blobs in Field arrray*/
167
 
 
168
 
private:
 
53
  KEY  *key_info;                       /* data of keys in database */
 
54
  uint  *blob_field;                    /* Index to blobs in Field arrray*/
 
55
 
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 */
173
 
 
174
 
public:
175
 
  size_t getNamedFieldSize() const
176
 
  {
177
 
    return name_hash.size();
178
 
  }
179
 
 
180
 
  Field **getNamedField(const std::string &arg)
181
 
  {
182
 
    FieldMap::iterator iter= name_hash.find(arg);
183
 
 
184
 
    if (iter == name_hash.end())
185
 
        return 0;
186
 
 
187
 
    return (*iter).second;
188
 
  }
189
 
 
190
 
private:
191
 
  memory::Root mem_root;
192
 
 
193
 
  void *alloc_root(size_t arg)
194
 
  {
195
 
    return mem_root.alloc_root(arg);
196
 
  }
197
 
 
198
 
  char *strmake_root(const char *str_arg, size_t len_arg)
199
 
  {
200
 
    return mem_root.strmake_root(str_arg, len_arg);
201
 
  }
202
 
 
203
 
  memory::Root *getMemRoot()
204
 
  {
205
 
    return &mem_root;
206
 
  }
207
 
 
208
 
  std::vector<std::string> _keynames;
209
 
 
210
 
  void addKeyName(std::string arg)
211
 
  {
212
 
    std::transform(arg.begin(), arg.end(),
213
 
                   arg.begin(), ::toupper);
214
 
    _keynames.push_back(arg);
215
 
  }
216
 
 
217
 
public:
218
 
  bool doesKeyNameExist(const char *name_arg, uint32_t name_length, uint32_t &position) const
219
 
  {
220
 
    return doesKeyNameExist(std::string(name_arg, name_length), position);
221
 
  }
222
 
 
223
 
  bool doesKeyNameExist(std::string arg, uint32_t &position) const
224
 
  {
225
 
    std::transform(arg.begin(), arg.end(),
226
 
                   arg.begin(), ::toupper);
227
 
 
228
 
    std::vector<std::string>::const_iterator iter= std::find(_keynames.begin(), _keynames.end(), arg);
229
 
 
230
 
    if (iter == _keynames.end())
231
 
    {
232
 
      position= UINT32_MAX; //historical, required for finding primary key from unique
233
 
      return false;
234
 
    }
235
 
 
236
 
    position= iter -  _keynames.begin();
237
 
 
238
 
    return true;
239
 
  }
240
 
 
241
 
private:
242
 
  std::vector<TYPELIB> intervals;                       /* pointer to interval info */
243
 
 
244
 
public:
245
 
  virtual void lock()
246
 
  { }
247
 
 
248
 
  virtual void unlock()
249
 
  { }
250
 
 
251
 
private:
252
 
  std::vector<unsigned char> default_values;            /* row with default values */
253
 
 
254
 
public:
255
 
  // @note This needs to be made to be const in the future
256
 
  unsigned char *getDefaultValues()
257
 
  {
258
 
    return &default_values[0];
259
 
  }
260
 
  void resizeDefaultValues(size_t arg)
261
 
  {
262
 
    default_values.resize(arg);
263
 
  }
264
 
 
265
 
  const charset_info_st *table_charset; /* Default charset of string fields */
266
 
 
267
 
  boost::dynamic_bitset<> all_set;
268
 
 
 
57
  HASH  name_hash;                      /* hash of field names */
 
58
  MEM_ROOT mem_root;
 
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 */
 
64
 
 
65
 
 
66
  unsigned char *default_values;                /* row with default values */
 
67
  const CHARSET_INFO *table_charset; /* Default charset of string fields */
 
68
 
 
69
  MyBitmap all_set;
269
70
  /*
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.
278
79
  */
279
 
private:
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) */
286
 
 
287
 
public:
288
 
 
289
 
  const char *getNormalizedPath() const
290
 
  {
291
 
    return normalized_path.str;
292
 
  }
293
 
 
294
 
  const char *getPath() const
295
 
  {
296
 
    return path.str;
297
 
  }
298
 
 
299
 
  const identifier::Table::Key& getCacheKey() const // This should never be called when we aren't looking at a cache.
300
 
  {
301
 
    assert(private_key_for_cache.size());
302
 
    return private_key_for_cache;
303
 
  }
304
 
 
305
 
  size_t getCacheKeySize() const
306
 
  {
307
 
    return private_key_for_cache.size();
308
 
  }
309
 
 
310
 
private:
311
 
  void setPath(char *str_arg, uint32_t size_arg)
312
 
  {
313
 
    path.str= str_arg;
314
 
    path.length= size_arg;
315
 
  }
316
 
 
317
 
  void setNormalizedPath(char *str_arg, uint32_t size_arg)
318
 
  {
319
 
    normalized_path.str= str_arg;
320
 
    normalized_path.length= size_arg;
321
 
  }
322
 
 
323
 
public:
324
 
 
325
 
  const char *getTableName() const
326
 
  {
327
 
    return table_name.str;
328
 
  }
329
 
 
330
 
  uint32_t getTableNameSize() const
331
 
  {
332
 
    return table_name.length;
333
 
  }
334
 
 
335
 
  const std::string &getTableName(std::string &name_arg) const
336
 
  {
337
 
    name_arg.clear();
338
 
    name_arg.append(table_name.str, table_name.length);
339
 
 
340
 
    return name_arg;
341
 
  }
342
 
 
343
 
  const char *getSchemaName() const
344
 
  {
345
 
    return db.str;
346
 
  }
347
 
 
348
 
  const std::string &getSchemaName(std::string &schema_name_arg) const
349
 
  {
350
 
    schema_name_arg.clear();
351
 
    schema_name_arg.append(db.str, db.length);
352
 
 
353
 
    return schema_name_arg;
354
 
  }
 
85
  LEX_STRING connect_string;
355
86
 
356
87
  uint32_t   block_size;                   /* create information */
357
 
 
358
 
private:
359
 
  uint64_t   version;
360
 
 
361
 
public:
362
 
  uint64_t getVersion() const
363
 
  {
364
 
    return version;
365
 
  }
366
 
 
367
 
  void refreshVersion();
368
 
 
369
 
  void resetVersion()
370
 
  {
371
 
    version= 0;
372
 
  }
373
 
 
374
 
private:
 
88
  uint32_t   version;
375
89
  uint32_t   timestamp_offset;          /* Set to offset+1 of record */
376
 
 
377
 
  uint32_t reclength;                   /* Recordlength */
378
 
  uint32_t stored_rec_length;         /* Stored record length*/
379
 
 
380
 
public:
381
 
  uint32_t sizeStoredRecord() const
382
 
  {
383
 
    return stored_rec_length;
384
 
  }
385
 
 
386
 
  uint32_t getRecordLength() const
387
 
  {
388
 
    return reclength;
389
 
  }
390
 
 
391
 
  void setRecordLength(uint32_t arg)
392
 
  {
393
 
    reclength= arg;
394
 
  }
395
 
 
396
 
  const Field_blob *getBlobFieldAt(uint32_t arg) const
397
 
  {
398
 
    if (arg < blob_fields)
399
 
      return (Field_blob*) _fields[blob_field[arg]];
400
 
 
401
 
    return NULL;
402
 
  }
 
90
  uint32_t   reclength;                 /* Recordlength */
 
91
  uint32_t   stored_rec_length;         /* Stored record length*/
 
92
  enum row_type row_type;               /* How rows are stored */
403
93
 
404
94
private:
405
95
  /* Max rows is a hint to HEAP during a create tmp table */
406
96
  uint64_t max_rows;
407
97
 
408
 
  boost::scoped_ptr<message::Table> _table_message;
409
 
 
 
98
  drizzled::message::Table *table_proto;
410
99
public:
411
 
  /*
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.
414
 
  */
415
 
  message::Table::TableType getTableType() const
416
 
  {
417
 
    return getTableMessage() ? getTableMessage()->type() : message::Table::STANDARD;
418
 
  }
419
 
 
420
 
  const std::string &getTableTypeAsString() const
421
 
  {
422
 
    if (getTableMessage())
423
 
      return message::type(getTableMessage()->type());
424
 
 
425
 
    return NO_PROTOBUFFER_AVAILABLE;
426
 
  }
427
100
 
428
101
  /* This is only used in one location currently */
429
 
  inline message::Table *getTableMessage() const
430
 
  {
431
 
    return _table_message.get();
432
 
  }
433
 
 
434
 
  void setTableMessage(const message::Table &arg)
435
 
  {
436
 
    assert(not getTableMessage());
437
 
    _table_message.reset(new(std::nothrow) message::Table(arg));
438
 
  }
439
 
 
440
 
  const message::Table::Field &field(int32_t field_position) const
441
 
  {
442
 
    assert(getTableMessage());
443
 
    return getTableMessage()->field(field_position);
444
 
  }
445
 
 
446
 
  inline bool hasComment() const
447
 
  {
448
 
    return (getTableMessage()) ?  getTableMessage()->options().has_comment() : false; 
 
102
  inline void setTableProto(drizzled::message::Table *arg)
 
103
  {
 
104
    assert(table_proto == NULL);
 
105
    table_proto= arg;
 
106
  }
 
107
 
 
108
  inline bool hasComment()
 
109
  {
 
110
    return (table_proto) ?  table_proto->options().has_comment() : false; 
449
111
  }
450
112
 
451
113
  inline const char *getComment()
452
114
  {
453
 
    return (getTableMessage() && getTableMessage()->has_options()) ?  getTableMessage()->options().comment().c_str() : NULL; 
 
115
    return (table_proto) ?  table_proto->options().comment().c_str() : NULL; 
454
116
  }
455
117
 
456
 
  inline uint32_t getCommentLength() const
 
118
  inline uint32_t getCommentLength()
457
119
  {
458
 
    return (getTableMessage()) ? getTableMessage()->options().comment().length() : 0; 
 
120
    return (table_proto) ? table_proto->options().comment().length() : 0; 
459
121
  }
460
122
 
461
 
  inline uint64_t getMaxRows() const
 
123
  inline uint64_t getMaxRows()
462
124
  {
463
125
    return max_rows;
464
126
  }
468
130
    max_rows= arg;
469
131
  }
470
132
 
471
 
  /**
472
 
   * Returns true if the supplied Field object
473
 
   * is part of the table's primary key.
474
 
 */
475
 
  bool fieldInPrimaryKey(Field *field) const;
476
 
 
477
 
  plugin::StorageEngine *storage_engine;                        /* storage engine plugin */
478
 
  inline plugin::StorageEngine *db_type() const /* table_type for handler */
479
 
  {
480
 
    return storage_engine;
481
 
  }
482
 
  inline plugin::StorageEngine *getEngine() const       /* table_type for handler */
483
 
  {
484
 
    return storage_engine;
485
 
  }
486
 
 
487
 
private:
488
 
  identifier::Table::Type tmp_table;
489
 
public:
490
 
 
491
 
  identifier::Table::Type getType() const
492
 
  {
493
 
    return tmp_table;
494
 
  }
495
 
 
496
 
private:
497
 
  uint32_t _ref_count;       /* How many Table objects uses this */
498
 
 
499
 
public:
500
 
  uint32_t getTableCount() const
501
 
  {
502
 
    return _ref_count;
503
 
  }
504
 
 
505
 
  void incrementTableCount()
506
 
  {
507
 
    lock();
508
 
    _ref_count++;
509
 
    unlock();
510
 
  }
511
 
 
512
 
  uint32_t decrementTableCount()
513
 
  {
514
 
    return --_ref_count;
515
 
  }
516
 
 
 
133
  StorageEngine *storage_engine;                        /* storage engine plugin */
 
134
  inline StorageEngine *db_type() const /* table_type for handler */
 
135
  {
 
136
    return storage_engine;
 
137
  }
 
138
  enum tmp_table_type tmp_table;
 
139
 
 
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;
519
 
private:
520
 
  uint32_t _field_size;                         /* Number of fields */
521
 
 
522
 
public:
523
 
  void setFieldSize(uint32_t arg)
524
 
  {
525
 
    _field_size= arg;
526
 
  }
527
 
 
528
 
  uint32_t sizeFields() const
529
 
  {
530
 
    return _field_size;
531
 
  }
532
 
 
 
144
  uint32_t fields;                              /* Number of fields */
533
145
  uint32_t rec_buff_length;                 /* Size of table->record[] buffer */
534
 
  uint32_t keys;
535
 
 
536
 
  uint32_t sizeKeys() const
537
 
  {
538
 
    return keys;
539
 
  }
540
 
  uint32_t key_parts;
 
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 */
545
 
private:
546
 
  bool has_variable_width;                  /* number of varchar fields */
547
 
 
548
 
public:
549
 
  bool hasVariableWidth() const
550
 
  {
551
 
    return has_variable_width; // We should calculate this.
552
 
  }
553
 
  void setVariableWidth()
554
 
  {
555
 
    has_variable_width= true;
556
 
  }
 
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 */
561
 
  /**
562
 
   * @TODO 
563
 
   *
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?
569
 
 */
570
 
private:
 
157
  /* Index of auto-updated TIMESTAMP field in field array */
571
158
  uint32_t primary_key;
572
 
public:
573
 
 
574
 
  uint32_t getPrimaryKey() const
575
 
  {
576
 
    return primary_key;
577
 
  }
578
 
 
579
 
  bool hasPrimaryKey() const
580
 
  {
581
 
    return primary_key != MAX_KEY;
582
 
  }
583
 
 
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;
589
164
 
590
 
private:
591
165
  uint8_t blob_ptr_size;                        /* 4 or 8 */
592
 
 
593
 
public:
594
 
  uint8_t sizeBlobPtr() const
595
 
  {
596
 
    return blob_ptr_size;
597
 
  }
598
 
 
599
166
  bool db_low_byte_first;               /* Portable row format */
 
167
  bool crashed;
 
168
  bool name_lock;
 
169
  bool replace_with_name_lock;
 
170
  bool waiting_on_cond;                 /* Protection against free */
600
171
 
601
172
  /*
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;
607
178
 
608
 
  /* 
609
 
    event_observers is a class containing all the event plugins that have 
610
 
    registered an interest in this table.
611
 
  */
612
 
  virtual plugin::EventObserverList *getTableObservers() 
613
 
  { 
614
 
    return NULL;
615
 
  }
616
 
  
617
 
  virtual void setTableObservers(plugin::EventObserverList *) 
618
 
  { }
619
 
  
620
179
  /*
621
 
    Set share's identifier information.
 
180
    Set share's table cache key and update its db and table name appropriately.
622
181
 
623
182
    SYNOPSIS
624
 
    setIdentifier()
 
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.
625
187
 
626
188
    NOTES
627
 
  */
628
 
 
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.
 
193
  */
 
194
 
 
195
  void set_table_cache_key(char *key_buff, uint32_t key_length)
 
196
  {
 
197
    table_cache_key.str= key_buff;
 
198
    table_cache_key.length= key_length;
 
199
    /*
 
200
      Let us use the fact that the key is "db/0/table_name/0" + optional
 
201
      part for temporary tables.
 
202
    */
 
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);
 
207
  }
 
208
 
 
209
 
 
210
  /*
 
211
    Set share's table cache key and update its db and table name appropriately.
 
212
 
 
213
    SYNOPSIS
 
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.
 
219
 
 
220
    NOTE
 
221
    Since 'key_buff' buffer will be used as storage for table cache key
 
222
    it should has same life-time as share itself.
 
223
  */
 
224
 
 
225
  void set_table_cache_key(char *key_buff, const char *key, uint32_t key_length)
 
226
  {
 
227
    memcpy(key_buff, key, key_length);
 
228
    set_table_cache_key(key_buff, key_length);
 
229
  }
 
230
 
 
231
  inline bool honor_global_locks()
 
232
  {
 
233
    return (table_category == TABLE_CATEGORY_USER);
 
234
  }
 
235
 
630
236
 
631
237
  /*
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
642
248
 
643
249
    NOTES
644
 
    
 
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
 
253
 
 
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).
645
257
  */
646
258
 
647
 
private:
 
259
  void init()
 
260
  {
 
261
    init("", 0, "", "");
 
262
  }
 
263
 
648
264
  void init(const char *new_table_name,
649
 
            const char *new_path);
650
 
 
651
 
protected:
 
265
            const char *new_path)
 
266
  {
 
267
    init("", 0, new_table_name, new_path);
 
268
  }
 
269
 
 
270
  void init(const char *key,
 
271
            uint32_t key_length, const char *new_table_name,
 
272
            const char *new_path)
 
273
  {
 
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;
 
278
    db.str=                 (char*) key;
 
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);
 
287
 
 
288
    return;
 
289
  }
 
290
 
 
291
  /*
 
292
    Free table share and memory used by it
 
293
 
 
294
    SYNOPSIS
 
295
    free_table_share()
 
296
    share               Table share
 
297
 
 
298
    NOTES
 
299
    share->mutex must be locked when we come here if it's not a temp table
 
300
  */
 
301
 
 
302
  void free_table_share()
 
303
  {
 
304
    MEM_ROOT new_mem_root;
 
305
    assert(ref_count == 0);
 
306
 
 
307
    /*
 
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.
 
310
    */
 
311
    if (tmp_table == NO_TMP_TABLE)
 
312
    {
 
313
      /* share->mutex is locked in release_table_share() */
 
314
      while (waiting_on_cond)
 
315
      {
 
316
        pthread_cond_broadcast(&cond);
 
317
        pthread_cond_wait(&cond, &mutex);
 
318
      }
 
319
      /* No thread refers to this anymore */
 
320
      pthread_mutex_unlock(&mutex);
 
321
      pthread_mutex_destroy(&mutex);
 
322
      pthread_cond_destroy(&cond);
 
323
    }
 
324
    hash_free(&name_hash);
 
325
 
 
326
    storage_engine= NULL;
 
327
 
 
328
    delete table_proto;
 
329
    table_proto= NULL;
 
330
 
 
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
 
334
  }
 
335
 
652
336
  void open_table_error(int pass_error, int db_errno, int pass_errarg);
653
337
 
654
 
public:
655
 
 
656
 
  static TableShare::shared_ptr getShareCreate(Session *session, 
657
 
                                               const identifier::Table &identifier,
658
 
                                               int &error);
659
 
 
660
 
  friend std::ostream& operator<<(std::ostream& output, const TableShare &share)
661
 
  {
662
 
    output << "TableShare:(";
663
 
    output <<  share.getSchemaName();
664
 
    output << ", ";
665
 
    output << share.getTableName();
666
 
    output << ", ";
667
 
    output << share.getTableTypeAsString();
668
 
    output << ", ";
669
 
    output << share.getPath();
670
 
    output << ")";
671
 
 
672
 
    return output;  // for multiple << operators.
673
 
  }
674
 
 
675
 
protected:
676
 
  friend class drizzled::table::Singular;
677
 
 
678
 
  Field *make_field(const message::Table::Field &pfield,
679
 
                    unsigned char *ptr,
680
 
                    uint32_t field_length,
681
 
                    bool is_nullable,
682
 
                    unsigned char *null_pos,
683
 
                    unsigned char null_bit,
684
 
                    uint8_t decimals,
685
 
                    enum_field_types field_type,
686
 
                    const charset_info_st * field_charset,
687
 
                    Field::utype unireg_check,
688
 
                    TYPELIB *interval,
689
 
                    const char *field_name);
690
 
 
691
 
  Field *make_field(const message::Table::Field &pfield,
692
 
                    unsigned char *ptr,
693
 
                    uint32_t field_length,
694
 
                    bool is_nullable,
695
 
                    unsigned char *null_pos,
696
 
                    unsigned char null_bit,
697
 
                    uint8_t decimals,
698
 
                    enum_field_types field_type,
699
 
                    const charset_info_st * field_charset,
700
 
                    Field::utype unireg_check,
701
 
                    TYPELIB *interval,
702
 
                    const char *field_name, 
703
 
                    bool is_unsigned);
704
 
 
705
 
public:
706
 
  int open_table_def(Session& session, const identifier::Table &identifier);
707
 
 
708
 
  int open_table_from_share(Session *session,
709
 
                            const identifier::Table &identifier,
710
 
                            const char *alias,
711
 
                            uint32_t db_stat, uint32_t ha_open_flags,
712
 
                            Table &outparam);
713
 
private:
714
 
  int open_table_from_share_inner(Session *session,
715
 
                                  const char *alias,
716
 
                                  uint32_t db_stat,
717
 
                                  Table &outparam);
718
 
  int open_table_cursor_inner(const identifier::Table &identifier,
719
 
                              uint32_t db_stat, uint32_t ha_open_flags,
720
 
                              Table &outparam,
721
 
                              bool &error_reported);
722
 
public:
723
 
  bool parse_table_proto(Session& session, message::Table &table);
 
338
 
 
339
 
 
340
  /*
 
341
    Create a table cache key
 
342
 
 
343
    SYNOPSIS
 
344
    createKey()
 
345
    key                 Create key here (must be of size MAX_DBKEY_LENGTH)
 
346
    table_list          Table definition
 
347
 
 
348
    IMPLEMENTATION
 
349
    The table cache_key is created from:
 
350
    db_name + \0
 
351
    table_name + \0
 
352
 
 
353
    if the table is a tmp table, we add the following to make each tmp table
 
354
    unique on the slave:
 
355
 
 
356
    4 bytes for master thread id
 
357
    4 bytes pseudo thread id
 
358
 
 
359
    RETURN
 
360
    Length of key
 
361
  */
 
362
 
 
363
  static inline uint32_t createKey(char *key, std::string& db_arg,
 
364
                                   std::string& table_name_arg)
 
365
  {
 
366
    return createKey(key, db_arg.c_str(), table_name_arg.c_str());
 
367
  }
 
368
 
 
369
  static inline uint32_t createKey(char *key, const char *db_arg, const char *table_name_arg)
 
370
  {
 
371
    uint32_t key_length;
 
372
    char *key_pos= key;
 
373
 
 
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;
 
378
 
 
379
    return key_length;
 
380
  }
 
381
 
 
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);
724
390
};
725
 
 
726
 
} /* namespace drizzled */
727
 
 
728
 
#endif /* DRIZZLED_TABLE_INSTANCE_BASE_H */