~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_share.h

  • Committer: Monty Taylor
  • Date: 2009-12-25 08:50:15 UTC
  • mto: This revision was merged to the branch mainline in revision 1255.
  • Revision ID: mordred@inaugust.com-20091225085015-83sux5qsvy312gew
MEM_ROOT == memory::Root

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
 
26
#ifndef DRIZZLED_TABLE_SHARE_H
 
27
#define DRIZZLED_TABLE_SHARE_H
28
28
 
29
29
#include <string>
30
30
 
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
31
#include "drizzled/typelib.h"
 
32
#include "drizzled/my_hash.h"
38
33
#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;
 
34
#include "drizzled/message/table.pb.h"
66
35
 
67
36
class TableShare
68
37
{
69
 
  typedef std::vector<std::string> StringVector;
70
 
 
71
38
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:
 
39
  TableShare() :
 
40
    table_category(TABLE_UNKNOWN_CATEGORY),
 
41
    open_count(0),
 
42
    field(NULL),
 
43
    found_next_number_field(NULL),
 
44
    timestamp_field(NULL),
 
45
    key_info(NULL),
 
46
    blob_field(NULL),
 
47
    intervals(NULL),
 
48
    default_values(NULL),
 
49
    block_size(0),
 
50
    version(0),
 
51
    timestamp_offset(0),
 
52
    reclength(0),
 
53
    stored_rec_length(0),
 
54
    row_type(ROW_TYPE_DEFAULT),
 
55
    max_rows(0),
 
56
    table_proto(NULL),
 
57
    storage_engine(NULL),
 
58
    tmp_table(NO_TMP_TABLE),
 
59
    ref_count(0),
 
60
    null_bytes(0),
 
61
    last_null_bit_pos(0),
 
62
    fields(0),
 
63
    rec_buff_length(0),
 
64
    keys(0),
 
65
    key_parts(0),
 
66
    max_key_length(0),
 
67
    max_unique_length(0),
 
68
    total_key_length(0),
 
69
    uniques(0),
 
70
    null_fields(0),
 
71
    blob_fields(0),
 
72
    timestamp_field_offset(0),
 
73
    varchar_fields(0),
 
74
    db_create_options(0),
 
75
    db_options_in_use(0),
 
76
    db_record_offset(0),
 
77
    rowid_field_offset(0),
 
78
    primary_key(0),
 
79
    next_number_index(0),
 
80
    next_number_key_offset(0),
 
81
    next_number_keypart(0),
 
82
    error(0),
 
83
    open_errno(0),
 
84
    errarg(0),
 
85
    column_bitmap_size(0),
 
86
    blob_ptr_size(0),
 
87
    db_low_byte_first(false),
 
88
    name_lock(false),
 
89
    replace_with_name_lock(false),
 
90
    waiting_on_cond(false),
 
91
    keys_in_use(0),
 
92
    keys_for_keyread(0)
 
93
  {
 
94
    init();
 
95
  }
 
96
 
 
97
  TableShare(const char *key,
 
98
             uint32_t key_length,
 
99
             const char *new_table_name,
 
100
             const char *new_path) :
 
101
    table_category(TABLE_UNKNOWN_CATEGORY),
 
102
    open_count(0),
 
103
    field(NULL),
 
104
    found_next_number_field(NULL),
 
105
    timestamp_field(NULL),
 
106
    key_info(NULL),
 
107
    blob_field(NULL),
 
108
    intervals(NULL),
 
109
    default_values(NULL),
 
110
    block_size(0),
 
111
    version(0),
 
112
    timestamp_offset(0),
 
113
    reclength(0),
 
114
    stored_rec_length(0),
 
115
    row_type(ROW_TYPE_DEFAULT),
 
116
    max_rows(0),
 
117
    table_proto(NULL),
 
118
    storage_engine(NULL),
 
119
    tmp_table(NO_TMP_TABLE),
 
120
    ref_count(0),
 
121
    null_bytes(0),
 
122
    last_null_bit_pos(0),
 
123
    fields(0),
 
124
    rec_buff_length(0),
 
125
    keys(0),
 
126
    key_parts(0),
 
127
    max_key_length(0),
 
128
    max_unique_length(0),
 
129
    total_key_length(0),
 
130
    uniques(0),
 
131
    null_fields(0),
 
132
    blob_fields(0),
 
133
    timestamp_field_offset(0),
 
134
    varchar_fields(0),
 
135
    db_create_options(0),
 
136
    db_options_in_use(0),
 
137
    db_record_offset(0),
 
138
    rowid_field_offset(0),
 
139
    primary_key(0),
 
140
    next_number_index(0),
 
141
    next_number_key_offset(0),
 
142
    next_number_keypart(0),
 
143
    error(0),
 
144
    open_errno(0),
 
145
    errarg(0),
 
146
    column_bitmap_size(0),
 
147
    blob_ptr_size(0),
 
148
    db_low_byte_first(false),
 
149
    name_lock(false),
 
150
    replace_with_name_lock(false),
 
151
    waiting_on_cond(false),
 
152
    keys_in_use(0),
 
153
    keys_for_keyread(0)
 
154
  {
 
155
    init(key, key_length, new_table_name, new_path);
 
156
  }
 
157
 
88
158
  /** Category of this table. */
89
159
  enum_table_category table_category;
90
160
 
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
 
  }
 
161
  uint32_t open_count;                  /* Number of tables in open list */
101
162
 
102
163
  /* 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
 
 
 
164
  Field **field;
140
165
  Field **found_next_number_field;
141
 
 
142
 
private:
143
166
  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:
 
167
  KEY  *key_info;                       /* data of keys in database */
 
168
  uint  *blob_field;                    /* Index to blobs in Field arrray*/
 
169
 
169
170
  /* 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
 
 
 
171
  HASH  name_hash;                      /* hash of field names */
 
172
  drizzled::memory::Root mem_root;
 
173
  TYPELIB keynames;                     /* Pointers to keynames */
 
174
  TYPELIB fieldnames;                   /* Pointer to fieldnames */
 
175
  TYPELIB *intervals;                   /* pointer to interval info */
 
176
  pthread_mutex_t mutex;                /* For locking the share  */
 
177
  pthread_cond_t cond;                  /* To signal that share is ready */
 
178
 
 
179
  unsigned char *default_values;                /* row with default values */
 
180
  const CHARSET_INFO *table_charset; /* Default charset of string fields */
 
181
 
 
182
  MyBitmap all_set;
269
183
  /*
270
184
    Key which is used for looking-up table in table cache and in the list
271
185
    of thread's temporary tables. Has the form of:
276
190
    should correspond to each other.
277
191
    To ensure this one can use set_table_cache() methods.
278
192
  */
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.
 
193
  LEX_STRING table_cache_key;
282
194
  LEX_STRING db;                        /* Pointer to db */
283
195
  LEX_STRING table_name;                /* Table name (for open) */
284
 
  LEX_STRING path;      /* Path to table (from datadir) */
 
196
  LEX_STRING path;      /* Path to .frm file (from datadir) */
285
197
  LEX_STRING normalized_path;           /* unpack_filename(path) */
286
198
 
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
 
  }
355
 
 
356
199
  uint32_t   block_size;                   /* create information */
357
 
 
358
 
private:
359
200
  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:
375
201
  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
 
  }
 
202
  uint32_t   reclength;                 /* Recordlength */
 
203
  uint32_t   stored_rec_length;         /* Stored record length*/
 
204
  enum row_type row_type;               /* How rows are stored */
403
205
 
404
206
private:
405
207
  /* Max rows is a hint to HEAP during a create tmp table */
406
208
  uint64_t max_rows;
407
209
 
408
 
  boost::scoped_ptr<message::Table> _table_message;
409
 
 
 
210
  drizzled::message::Table *table_proto;
410
211
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
212
 
428
213
  /* 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; 
 
214
  inline void setTableProto(drizzled::message::Table *arg)
 
215
  {
 
216
    assert(table_proto == NULL);
 
217
    table_proto= arg;
 
218
  }
 
219
 
 
220
  inline bool hasComment()
 
221
  {
 
222
    return (table_proto) ?  table_proto->options().has_comment() : false; 
449
223
  }
450
224
 
451
225
  inline const char *getComment()
452
226
  {
453
 
    return (getTableMessage() && getTableMessage()->has_options()) ?  getTableMessage()->options().comment().c_str() : NULL; 
454
 
  }
455
 
 
456
 
  inline uint32_t getCommentLength() const
457
 
  {
458
 
    return (getTableMessage()) ? getTableMessage()->options().comment().length() : 0; 
459
 
  }
460
 
 
461
 
  inline uint64_t getMaxRows() const
 
227
    return (table_proto && table_proto->has_options()) ?  table_proto->options().comment().c_str() : NULL; 
 
228
  }
 
229
 
 
230
  inline uint32_t getCommentLength()
 
231
  {
 
232
    return (table_proto) ? table_proto->options().comment().length() : 0; 
 
233
  }
 
234
 
 
235
  inline bool hasKeyBlockSize()
 
236
  {
 
237
    return (table_proto) ? table_proto->options().has_key_block_size() : false;
 
238
  }
 
239
 
 
240
  inline uint32_t getKeyBlockSize()
 
241
  {
 
242
    return (table_proto) ? table_proto->options().key_block_size() : 0;
 
243
  }
 
244
 
 
245
  inline uint64_t getMaxRows()
462
246
  {
463
247
    return max_rows;
464
248
  }
468
252
    max_rows= arg;
469
253
  }
470
254
 
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
 
 
 
255
  drizzled::plugin::StorageEngine *storage_engine;                      /* storage engine plugin */
 
256
  inline drizzled::plugin::StorageEngine *db_type() const       /* table_type for handler */
 
257
  {
 
258
    return storage_engine;
 
259
  }
 
260
  inline drizzled::plugin::StorageEngine *getEngine() const     /* table_type for handler */
 
261
  {
 
262
    return storage_engine;
 
263
  }
 
264
  enum tmp_table_type tmp_table;
 
265
 
 
266
  uint32_t ref_count;       /* How many Table objects uses this */
517
267
  uint32_t null_bytes;
518
268
  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
 
 
 
269
  uint32_t fields;                              /* Number of fields */
533
270
  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;
 
271
  uint32_t keys, key_parts;
541
272
  uint32_t max_key_length, max_unique_length, total_key_length;
542
273
  uint32_t uniques;                         /* Number of UNIQUE index */
543
274
  uint32_t null_fields;                 /* number of null fields */
544
275
  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
 
  }
 
276
  uint32_t timestamp_field_offset;              /* Field number for timestamp field */
 
277
  uint32_t varchar_fields;                  /* number of varchar fields */
557
278
  uint32_t db_create_options;           /* Create options from database */
558
279
  uint32_t db_options_in_use;           /* Options in use */
559
280
  uint32_t db_record_offset;            /* if HA_REC_IN_SEQ */
566
287
   * primary key.  However, as it exists, because this member is scalar, it
567
288
   * only supports a single-column primary key. Is there a better way
568
289
   * to ask for the fields which are in a primary key?
569
 
 */
570
 
private:
 
290
   */
571
291
  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
292
  /* Index of auto-updated TIMESTAMP field in field array */
585
293
  uint32_t next_number_index;               /* autoincrement key number */
586
294
  uint32_t next_number_key_offset;          /* autoinc keypart offset in a key */
587
295
  uint32_t next_number_keypart;             /* autoinc keypart number in a key */
588
296
  uint32_t error, open_errno, errarg;       /* error from open_table_def() */
 
297
  uint32_t column_bitmap_size;
589
298
 
590
 
private:
591
299
  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
300
  bool db_low_byte_first;               /* Portable row format */
 
301
  bool name_lock;
 
302
  bool replace_with_name_lock;
 
303
  bool waiting_on_cond;                 /* Protection against free */
600
304
 
601
305
  /*
602
306
    Set of keys in use, implemented as a Bitmap.
605
309
  key_map keys_in_use;
606
310
  key_map keys_for_keyread;
607
311
 
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
312
  /*
621
 
    Set share's identifier information.
 
313
    Set share's table cache key and update its db and table name appropriately.
622
314
 
623
315
    SYNOPSIS
624
 
    setIdentifier()
 
316
    set_table_cache_key()
 
317
    key_buff    Buffer with already built table cache key to be
 
318
    referenced from share.
 
319
    key_length  Key length.
625
320
 
626
321
    NOTES
627
 
  */
628
 
 
629
 
  void setIdentifier(const identifier::Table &identifier_arg);
 
322
    Since 'key_buff' buffer will be referenced from share it should has same
 
323
    life-time as share itself.
 
324
    This method automatically ensures that TableShare::table_name/db have
 
325
    appropriate values by using table cache key as their source.
 
326
  */
 
327
 
 
328
  void set_table_cache_key(char *key_buff, uint32_t key_length)
 
329
  {
 
330
    table_cache_key.str= key_buff;
 
331
    table_cache_key.length= key_length;
 
332
    /*
 
333
      Let us use the fact that the key is "db/0/table_name/0" + optional
 
334
      part for temporary tables.
 
335
    */
 
336
    db.str=            table_cache_key.str;
 
337
    db.length=         strlen(db.str);
 
338
    table_name.str=    db.str + db.length + 1;
 
339
    table_name.length= strlen(table_name.str);
 
340
  }
 
341
 
 
342
 
 
343
  /*
 
344
    Set share's table cache key and update its db and table name appropriately.
 
345
 
 
346
    SYNOPSIS
 
347
    set_table_cache_key()
 
348
    key_buff    Buffer to be used as storage for table cache key
 
349
    (should be at least key_length bytes).
 
350
    key         Value for table cache key.
 
351
    key_length  Key length.
 
352
 
 
353
    NOTE
 
354
    Since 'key_buff' buffer will be used as storage for table cache key
 
355
    it should has same life-time as share itself.
 
356
  */
 
357
 
 
358
  void set_table_cache_key(char *key_buff, const char *key, uint32_t key_length)
 
359
  {
 
360
    memcpy(key_buff, key, key_length);
 
361
    set_table_cache_key(key_buff, key_length);
 
362
  }
 
363
 
 
364
  inline bool honor_global_locks()
 
365
  {
 
366
    return (table_category == TABLE_CATEGORY_USER);
 
367
  }
 
368
 
630
369
 
631
370
  /*
632
371
    Initialize share for temporary tables
638
377
    must start with db name.
639
378
    key_length  Length of key
640
379
    table_name  Table name
641
 
    path        Path to table (possible in lower case)
 
380
    path        Path to file (possible in lower case) without .frm
642
381
 
643
382
    NOTES
644
 
    
 
383
    This is different from alloc_table_share() because temporary tables
 
384
    don't have to be shared between threads or put into the table def
 
385
    cache, so we can do some things notable simpler and faster
 
386
 
 
387
    If table is not put in session->temporary_tables (happens only when
 
388
    one uses OPEN TEMPORARY) then one can specify 'db' as key and
 
389
    use key_length= 0 as neither table_cache_key or key_length will be used).
645
390
  */
646
391
 
647
 
private:
 
392
  void init()
 
393
  {
 
394
    init("", 0, "", "");
 
395
  }
 
396
 
648
397
  void init(const char *new_table_name,
649
 
            const char *new_path);
650
 
 
651
 
protected:
 
398
            const char *new_path)
 
399
  {
 
400
    init("", 0, new_table_name, new_path);
 
401
  }
 
402
 
 
403
  void init(const char *key,
 
404
            uint32_t key_length, const char *new_table_name,
 
405
            const char *new_path)
 
406
  {
 
407
    memset(this, 0, sizeof(TableShare));
 
408
    init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
409
    table_category=         TABLE_CATEGORY_TEMPORARY;
 
410
    tmp_table=              INTERNAL_TMP_TABLE;
 
411
    db.str=                 (char*) key;
 
412
    db.length=           strlen(key);
 
413
    table_cache_key.str=    (char*) key;
 
414
    table_cache_key.length= key_length;
 
415
    table_name.str=         (char*) new_table_name;
 
416
    table_name.length=      strlen(new_table_name);
 
417
    path.str=               (char*) new_path;
 
418
    normalized_path.str=    (char*) new_path;
 
419
    path.length= normalized_path.length= strlen(new_path);
 
420
 
 
421
    return;
 
422
  }
 
423
 
 
424
  /*
 
425
    Free table share and memory used by it
 
426
 
 
427
    SYNOPSIS
 
428
    free_table_share()
 
429
    share               Table share
 
430
 
 
431
    NOTES
 
432
    share->mutex must be locked when we come here if it's not a temp table
 
433
  */
 
434
 
 
435
  void free_table_share()
 
436
  {
 
437
    drizzled::memory::Root new_mem_root;
 
438
    assert(ref_count == 0);
 
439
 
 
440
    /*
 
441
      If someone is waiting for this to be deleted, inform it about this.
 
442
      Don't do a delete until we know that no one is refering to this anymore.
 
443
    */
 
444
    if (tmp_table == NO_TMP_TABLE)
 
445
    {
 
446
      /* share->mutex is locked in release_table_share() */
 
447
      while (waiting_on_cond)
 
448
      {
 
449
        pthread_cond_broadcast(&cond);
 
450
        pthread_cond_wait(&cond, &mutex);
 
451
      }
 
452
      /* No thread refers to this anymore */
 
453
      pthread_mutex_unlock(&mutex);
 
454
      pthread_mutex_destroy(&mutex);
 
455
      pthread_cond_destroy(&cond);
 
456
    }
 
457
    hash_free(&name_hash);
 
458
 
 
459
    storage_engine= NULL;
 
460
 
 
461
    delete table_proto;
 
462
    table_proto= NULL;
 
463
 
 
464
    /* We must copy mem_root from share because share is allocated through it */
 
465
    memcpy(&new_mem_root, &mem_root, sizeof(new_mem_root));
 
466
    free_root(&new_mem_root, MYF(0));                 // Free's share
 
467
  }
 
468
 
652
469
  void open_table_error(int pass_error, int db_errno, int pass_errarg);
653
470
 
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);
 
471
 
 
472
 
 
473
  /*
 
474
    Create a table cache key
 
475
 
 
476
    SYNOPSIS
 
477
    createKey()
 
478
    key                 Create key here (must be of size MAX_DBKEY_LENGTH)
 
479
    table_list          Table definition
 
480
 
 
481
    IMPLEMENTATION
 
482
    The table cache_key is created from:
 
483
    db_name + \0
 
484
    table_name + \0
 
485
 
 
486
    if the table is a tmp table, we add the following to make each tmp table
 
487
    unique on the slave:
 
488
 
 
489
    4 bytes for master thread id
 
490
    4 bytes pseudo thread id
 
491
 
 
492
    RETURN
 
493
    Length of key
 
494
  */
 
495
 
 
496
  static inline uint32_t createKey(char *key, std::string& db_arg,
 
497
                                   std::string& table_name_arg)
 
498
  {
 
499
    return createKey(key, db_arg.c_str(), table_name_arg.c_str());
 
500
  }
 
501
 
 
502
  static inline uint32_t createKey(char *key, const char *db_arg, const char *table_name_arg)
 
503
  {
 
504
    uint32_t key_length;
 
505
    char *key_pos= key;
 
506
 
 
507
    key_pos= strcpy(key_pos, db_arg) + strlen(db_arg);
 
508
    key_pos= strcpy(key_pos+1, table_name_arg) +
 
509
      strlen(table_name_arg);
 
510
    key_length= (uint32_t)(key_pos-key)+1;
 
511
 
 
512
    return key_length;
 
513
  }
 
514
 
 
515
  static void cacheStart(void);
 
516
  static void cacheStop(void);
 
517
  static void release(TableShare *share);
 
518
  static void release(const char *key, uint32_t key_length);
 
519
  static TableShare *getShare(const char *db, const char *table_name);
 
520
  static TableShare *getShare(Session *session, 
 
521
                              TableList *table_list, char *key,
 
522
                              uint32_t key_length, uint32_t, int *error);
724
523
};
725
524
 
726
 
} /* namespace drizzled */
727
 
 
728
 
#endif /* DRIZZLED_TABLE_INSTANCE_BASE_H */
 
525
#endif /* DRIZZLED_TABLE_SHARE_H */