~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_share.h

  • Committer: Brian Aker
  • Date: 2010-05-27 01:25:56 UTC
  • mfrom: (1567.1.4 new-staging)
  • Revision ID: brian@gaz-20100527012556-5zgkirkl7swbigd6
Merge of Brian, Paul. PBXT compile issue, and test framework cleanup. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2009 Sun Microsystems
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 2 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, write to the Free Software
 
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
19
 */
 
20
 
 
21
/*
 
22
  This class is shared between different table objects. There is one
 
23
  instance of table share per one table in the database.
 
24
*/
 
25
 
 
26
#ifndef DRIZZLED_TABLE_SHARE_H
 
27
#define DRIZZLED_TABLE_SHARE_H
 
28
 
 
29
#include <string>
 
30
 
 
31
#include <drizzled/unordered_map.h>
 
32
 
 
33
#include "drizzled/typelib.h"
 
34
#include "drizzled/my_hash.h"
 
35
#include "drizzled/memory/root.h"
 
36
#include "drizzled/message/table.pb.h"
 
37
 
 
38
namespace drizzled
 
39
{
 
40
 
 
41
typedef unordered_map<std::string, TableShare *> TableDefinitionCache;
 
42
 
 
43
const static std::string STANDARD_STRING("STANDARD");
 
44
const static std::string TEMPORARY_STRING("TEMPORARY");
 
45
const static std::string INTERNAL_STRING("INTERNAL");
 
46
const static std::string FUNCTION_STRING("FUNCTION");
 
47
 
 
48
namespace plugin
 
49
{
 
50
class EventObserverList;
 
51
}
 
52
 
 
53
class TableShare
 
54
{
 
55
  typedef std::vector<std::string> StringVector;
 
56
public:
 
57
  TableShare() :
 
58
    table_category(TABLE_UNKNOWN_CATEGORY),
 
59
    open_count(0),
 
60
    field(NULL),
 
61
    found_next_number_field(NULL),
 
62
    timestamp_field(NULL),
 
63
    key_info(NULL),
 
64
    blob_field(NULL),
 
65
    intervals(NULL),
 
66
    default_values(NULL),
 
67
    block_size(0),
 
68
    version(0),
 
69
    timestamp_offset(0),
 
70
    reclength(0),
 
71
    stored_rec_length(0),
 
72
    row_type(ROW_TYPE_DEFAULT),
 
73
    max_rows(0),
 
74
    table_proto(NULL),
 
75
    storage_engine(NULL),
 
76
    tmp_table(message::Table::STANDARD),
 
77
    ref_count(0),
 
78
    null_bytes(0),
 
79
    last_null_bit_pos(0),
 
80
    fields(0),
 
81
    rec_buff_length(0),
 
82
    keys(0),
 
83
    key_parts(0),
 
84
    max_key_length(0),
 
85
    max_unique_length(0),
 
86
    total_key_length(0),
 
87
    uniques(0),
 
88
    null_fields(0),
 
89
    blob_fields(0),
 
90
    timestamp_field_offset(0),
 
91
    varchar_fields(0),
 
92
    db_create_options(0),
 
93
    db_options_in_use(0),
 
94
    db_record_offset(0),
 
95
    rowid_field_offset(0),
 
96
    primary_key(0),
 
97
    next_number_index(0),
 
98
    next_number_key_offset(0),
 
99
    next_number_keypart(0),
 
100
    error(0),
 
101
    open_errno(0),
 
102
    errarg(0),
 
103
    column_bitmap_size(0),
 
104
    blob_ptr_size(0),
 
105
    db_low_byte_first(false),
 
106
    name_lock(false),
 
107
    replace_with_name_lock(false),
 
108
    waiting_on_cond(false),
 
109
    keys_in_use(0),
 
110
    keys_for_keyread(0),
 
111
    event_observers(NULL),
 
112
    newed(true)
 
113
  {
 
114
    memset(&name_hash, 0, sizeof(HASH));
 
115
 
 
116
    table_charset= 0;
 
117
    memset(&all_set, 0, sizeof (MyBitmap));
 
118
    memset(&table_cache_key, 0, sizeof(LEX_STRING));
 
119
    memset(&db, 0, sizeof(LEX_STRING));
 
120
    memset(&table_name, 0, sizeof(LEX_STRING));
 
121
    memset(&path, 0, sizeof(LEX_STRING));
 
122
    memset(&normalized_path, 0, sizeof(LEX_STRING));
 
123
 
 
124
    init();
 
125
  }
 
126
 
 
127
  TableShare(const char *key,
 
128
             uint32_t key_length,
 
129
             const char *new_table_name,
 
130
             const char *new_path) :
 
131
    table_category(TABLE_UNKNOWN_CATEGORY),
 
132
    open_count(0),
 
133
    field(NULL),
 
134
    found_next_number_field(NULL),
 
135
    timestamp_field(NULL),
 
136
    key_info(NULL),
 
137
    blob_field(NULL),
 
138
    intervals(NULL),
 
139
    default_values(NULL),
 
140
    block_size(0),
 
141
    version(0),
 
142
    timestamp_offset(0),
 
143
    reclength(0),
 
144
    stored_rec_length(0),
 
145
    row_type(ROW_TYPE_DEFAULT),
 
146
    max_rows(0),
 
147
    table_proto(NULL),
 
148
    storage_engine(NULL),
 
149
    tmp_table(message::Table::STANDARD),
 
150
    ref_count(0),
 
151
    null_bytes(0),
 
152
    last_null_bit_pos(0),
 
153
    fields(0),
 
154
    rec_buff_length(0),
 
155
    keys(0),
 
156
    key_parts(0),
 
157
    max_key_length(0),
 
158
    max_unique_length(0),
 
159
    total_key_length(0),
 
160
    uniques(0),
 
161
    null_fields(0),
 
162
    blob_fields(0),
 
163
    timestamp_field_offset(0),
 
164
    varchar_fields(0),
 
165
    db_create_options(0),
 
166
    db_options_in_use(0),
 
167
    db_record_offset(0),
 
168
    rowid_field_offset(0),
 
169
    primary_key(0),
 
170
    next_number_index(0),
 
171
    next_number_key_offset(0),
 
172
    next_number_keypart(0),
 
173
    error(0),
 
174
    open_errno(0),
 
175
    errarg(0),
 
176
    column_bitmap_size(0),
 
177
    blob_ptr_size(0),
 
178
    db_low_byte_first(false),
 
179
    name_lock(false),
 
180
    replace_with_name_lock(false),
 
181
    waiting_on_cond(false),
 
182
    keys_in_use(0),
 
183
    keys_for_keyread(0),
 
184
    event_observers(NULL),
 
185
    newed(true)
 
186
  {
 
187
    memset(&name_hash, 0, sizeof(HASH));
 
188
 
 
189
    table_charset= 0;
 
190
    memset(&all_set, 0, sizeof (MyBitmap));
 
191
    memset(&table_cache_key, 0, sizeof(LEX_STRING));
 
192
    memset(&db, 0, sizeof(LEX_STRING));
 
193
    memset(&table_name, 0, sizeof(LEX_STRING));
 
194
    memset(&path, 0, sizeof(LEX_STRING));
 
195
    memset(&normalized_path, 0, sizeof(LEX_STRING));
 
196
    init(key, key_length, new_table_name, new_path);
 
197
  }
 
198
 
 
199
  TableShare(char *key, uint32_t key_length, char *path_arg= NULL, uint32_t path_length_arg= 0);
 
200
 
 
201
  ~TableShare() 
 
202
  {
 
203
    assert(ref_count == 0);
 
204
 
 
205
    /*
 
206
      If someone is waiting for this to be deleted, inform it about this.
 
207
      Don't do a delete until we know that no one is refering to this anymore.
 
208
    */
 
209
    if (tmp_table == message::Table::STANDARD)
 
210
    {
 
211
      /* share->mutex is locked in release_table_share() */
 
212
      while (waiting_on_cond)
 
213
      {
 
214
        pthread_cond_broadcast(&cond);
 
215
        pthread_cond_wait(&cond, &mutex);
 
216
      }
 
217
      /* No thread refers to this anymore */
 
218
      pthread_mutex_unlock(&mutex);
 
219
      pthread_mutex_destroy(&mutex);
 
220
      pthread_cond_destroy(&cond);
 
221
    }
 
222
    hash_free(&name_hash);
 
223
 
 
224
    storage_engine= NULL;
 
225
 
 
226
    delete table_proto;
 
227
    table_proto= NULL;
 
228
 
 
229
    mem_root.free_root(MYF(0));                 // Free's share
 
230
  };
 
231
 
 
232
private:
 
233
  /** Category of this table. */
 
234
  enum_table_category table_category;
 
235
 
 
236
  uint32_t open_count;                  /* Number of tables in open list */
 
237
public:
 
238
 
 
239
  bool isTemporaryCategory() const
 
240
  {
 
241
    return (table_category == TABLE_CATEGORY_TEMPORARY);
 
242
  }
 
243
 
 
244
  void setTableCategory(enum_table_category arg)
 
245
  {
 
246
    table_category= arg;
 
247
  }
 
248
 
 
249
  /* The following is copied to each Table on OPEN */
 
250
private:
 
251
  Field **field;
 
252
public:
 
253
  Field ** getFields()
 
254
  {
 
255
    return field;
 
256
  }
 
257
 
 
258
 
 
259
  Field **found_next_number_field;
 
260
  Field *timestamp_field;               /* Used only during open */
 
261
  KeyInfo  *key_info;                   /* data of keys in database */
 
262
  uint  *blob_field;                    /* Index to blobs in Field arrray*/
 
263
 
 
264
  /* hash of field names (contains pointers to elements of field array) */
 
265
  HASH  name_hash;                      /* hash of field names */
 
266
private:
 
267
  memory::Root mem_root;
 
268
public:
 
269
  void *alloc_root(size_t arg)
 
270
  {
 
271
    return mem_root.alloc_root(arg);
 
272
  }
 
273
 
 
274
  char *strmake_root(const char *str_arg, size_t len_arg)
 
275
  {
 
276
    return mem_root.strmake_root(str_arg, len_arg);
 
277
  }
 
278
 
 
279
  memory::Root *getMemRoot()
 
280
  {
 
281
    return &mem_root;
 
282
  }
 
283
 
 
284
private:
 
285
  std::vector<std::string> _keynames;
 
286
 
 
287
  void addKeyName(std::string arg)
 
288
  {
 
289
    std::transform(arg.begin(), arg.end(),
 
290
                   arg.begin(), ::toupper);
 
291
    _keynames.push_back(arg);
 
292
  }
 
293
public:
 
294
  bool doesKeyNameExist(const char *name_arg, uint32_t name_length, uint32_t &position)
 
295
  {
 
296
    std::string arg(name_arg, name_length);
 
297
    std::transform(arg.begin(), arg.end(),
 
298
                   arg.begin(), ::toupper);
 
299
 
 
300
    std::vector<std::string>::iterator iter= std::find(_keynames.begin(), _keynames.end(), arg);
 
301
 
 
302
    if (iter == _keynames.end())
 
303
      return false;
 
304
 
 
305
    position= iter -  _keynames.begin();
 
306
 
 
307
    return true;
 
308
  }
 
309
 
 
310
  bool doesKeyNameExist(std::string arg, uint32_t &position)
 
311
  {
 
312
    std::transform(arg.begin(), arg.end(),
 
313
                   arg.begin(), ::toupper);
 
314
 
 
315
    std::vector<std::string>::iterator iter= std::find(_keynames.begin(), _keynames.end(), arg);
 
316
 
 
317
    if (iter == _keynames.end())
 
318
    {
 
319
      position= -1; //historical, required for finding primary key from unique
 
320
      return false;
 
321
    }
 
322
 
 
323
    position= iter -  _keynames.begin();
 
324
 
 
325
    return true;
 
326
  }
 
327
 
 
328
private:
 
329
  TYPELIB *intervals;                   /* pointer to interval info */
 
330
 
 
331
public:
 
332
  pthread_mutex_t mutex;                /* For locking the share  */
 
333
  pthread_cond_t cond;                  /* To signal that share is ready */
 
334
 
 
335
  unsigned char *default_values;                /* row with default values */
 
336
  const CHARSET_INFO *table_charset; /* Default charset of string fields */
 
337
 
 
338
  MyBitmap all_set;
 
339
  /*
 
340
    Key which is used for looking-up table in table cache and in the list
 
341
    of thread's temporary tables. Has the form of:
 
342
    "database_name\0table_name\0" + optional part for temporary tables.
 
343
 
 
344
    Note that all three 'table_cache_key', 'db' and 'table_name' members
 
345
    must be set (and be non-zero) for tables in table cache. They also
 
346
    should correspond to each other.
 
347
    To ensure this one can use set_table_cache() methods.
 
348
  */
 
349
private:
 
350
  LEX_STRING table_cache_key;                        /* Pointer to db */
 
351
  LEX_STRING db;                        /* Pointer to db */
 
352
  LEX_STRING table_name;                /* Table name (for open) */
 
353
  LEX_STRING path;      /* Path to table (from datadir) */
 
354
  LEX_STRING normalized_path;           /* unpack_filename(path) */
 
355
public:
 
356
 
 
357
  const char *getNormalizedPath()
 
358
  {
 
359
    return normalized_path.str;
 
360
  }
 
361
 
 
362
  const char *getPath()
 
363
  {
 
364
    return path.str;
 
365
  }
 
366
 
 
367
  const char *getCacheKey()
 
368
  {
 
369
    return table_cache_key.str;
 
370
  }
 
371
 
 
372
  size_t getCacheKeySize() const
 
373
  {
 
374
    return table_cache_key.length;
 
375
  }
 
376
 
 
377
  void setPath(char *str_arg, uint32_t size_arg)
 
378
  {
 
379
    path.str= str_arg;
 
380
    path.length= size_arg;
 
381
  }
 
382
 
 
383
  void setNormalizedPath(char *str_arg, uint32_t size_arg)
 
384
  {
 
385
    normalized_path.str= str_arg;
 
386
    normalized_path.length= size_arg;
 
387
  }
 
388
 
 
389
  const char *getTableName() const
 
390
  {
 
391
    return table_name.str;
 
392
  }
 
393
 
 
394
  uint32_t getTableNameSize() const
 
395
  {
 
396
    return table_name.length;
 
397
  }
 
398
 
 
399
  const char *getTableCacheKey() const
 
400
  {
 
401
    return table_cache_key.str;
 
402
  }
 
403
 
 
404
  const char *getPath() const
 
405
  {
 
406
    return path.str;
 
407
  }
 
408
 
 
409
  const std::string &getTableName(std::string &name_arg) const
 
410
  {
 
411
    name_arg.clear();
 
412
    name_arg.append(table_name.str, table_name.length);
 
413
 
 
414
    return name_arg;
 
415
  }
 
416
 
 
417
  const char *getSchemaName() const
 
418
  {
 
419
    return db.str;
 
420
  }
 
421
 
 
422
  const std::string &getSchemaName(std::string &schema_name_arg) const
 
423
  {
 
424
    schema_name_arg.clear();
 
425
    schema_name_arg.append(db.str, db.length);
 
426
 
 
427
    return schema_name_arg;
 
428
  }
 
429
 
 
430
  uint32_t   block_size;                   /* create information */
 
431
 
 
432
  uint64_t   version;
 
433
  uint64_t getVersion()
 
434
  {
 
435
    return version;
 
436
  }
 
437
 
 
438
  uint32_t   timestamp_offset;          /* Set to offset+1 of record */
 
439
  uint32_t   reclength;                 /* Recordlength */
 
440
  uint32_t   stored_rec_length;         /* Stored record length*/
 
441
  enum row_type row_type;               /* How rows are stored */
 
442
 
 
443
  uint32_t getRecordLength()
 
444
  {
 
445
    return reclength;
 
446
  }
 
447
 
 
448
private:
 
449
  /* Max rows is a hint to HEAP during a create tmp table */
 
450
  uint64_t max_rows;
 
451
 
 
452
  message::Table *table_proto;
 
453
public:
 
454
 
 
455
  const std::string &getTableTypeAsString() const
 
456
  {
 
457
    switch (table_proto->type())
 
458
    {
 
459
    default:
 
460
    case message::Table::STANDARD:
 
461
      return STANDARD_STRING;
 
462
    case message::Table::TEMPORARY:
 
463
      return TEMPORARY_STRING;
 
464
    case message::Table::INTERNAL:
 
465
      return INTERNAL_STRING;
 
466
    case message::Table::FUNCTION:
 
467
      return FUNCTION_STRING;
 
468
    }
 
469
  }
 
470
 
 
471
  /* This is only used in one location currently */
 
472
  inline message::Table *getTableProto() const
 
473
  {
 
474
    return table_proto;
 
475
  }
 
476
 
 
477
  inline void setTableProto(message::Table *arg)
 
478
  {
 
479
    assert(table_proto == NULL);
 
480
    table_proto= arg;
 
481
  }
 
482
 
 
483
  inline bool hasComment()
 
484
  {
 
485
    return (table_proto) ?  table_proto->options().has_comment() : false; 
 
486
  }
 
487
 
 
488
  inline const char *getComment()
 
489
  {
 
490
    return (table_proto && table_proto->has_options()) ?  table_proto->options().comment().c_str() : NULL; 
 
491
  }
 
492
 
 
493
  inline uint32_t getCommentLength()
 
494
  {
 
495
    return (table_proto) ? table_proto->options().comment().length() : 0; 
 
496
  }
 
497
 
 
498
  inline uint64_t getMaxRows() const
 
499
  {
 
500
    return max_rows;
 
501
  }
 
502
 
 
503
  inline void setMaxRows(uint64_t arg)
 
504
  {
 
505
    max_rows= arg;
 
506
  }
 
507
 
 
508
  /**
 
509
   * Returns true if the supplied Field object
 
510
   * is part of the table's primary key.
 
511
 */
 
512
  bool fieldInPrimaryKey(Field *field) const;
 
513
 
 
514
  plugin::StorageEngine *storage_engine;                        /* storage engine plugin */
 
515
  inline plugin::StorageEngine *db_type() const /* table_type for handler */
 
516
  {
 
517
    return storage_engine;
 
518
  }
 
519
  inline plugin::StorageEngine *getEngine() const       /* table_type for handler */
 
520
  {
 
521
    return storage_engine;
 
522
  }
 
523
 
 
524
  TableIdentifier::Type tmp_table;
 
525
 
 
526
  uint32_t ref_count;       /* How many Table objects uses this */
 
527
  uint32_t getTableCount()
 
528
  {
 
529
    return ref_count;
 
530
  }
 
531
 
 
532
  uint32_t null_bytes;
 
533
  uint32_t last_null_bit_pos;
 
534
  uint32_t fields;                              /* Number of fields */
 
535
  uint32_t rec_buff_length;                 /* Size of table->record[] buffer */
 
536
  uint32_t keys, key_parts;
 
537
  uint32_t max_key_length, max_unique_length, total_key_length;
 
538
  uint32_t uniques;                         /* Number of UNIQUE index */
 
539
  uint32_t null_fields;                 /* number of null fields */
 
540
  uint32_t blob_fields;                 /* number of blob fields */
 
541
  uint32_t timestamp_field_offset;              /* Field number for timestamp field */
 
542
  uint32_t varchar_fields;                  /* number of varchar fields */
 
543
  uint32_t db_create_options;           /* Create options from database */
 
544
  uint32_t db_options_in_use;           /* Options in use */
 
545
  uint32_t db_record_offset;            /* if HA_REC_IN_SEQ */
 
546
  uint32_t rowid_field_offset;          /* Field_nr +1 to rowid field */
 
547
  /**
 
548
   * @TODO 
 
549
   *
 
550
   * Currently the replication services component uses
 
551
   * the primary_key member to determine which field is the table's
 
552
   * primary key.  However, as it exists, because this member is scalar, it
 
553
   * only supports a single-column primary key. Is there a better way
 
554
   * to ask for the fields which are in a primary key?
 
555
 */
 
556
  uint32_t primary_key;
 
557
  /* Index of auto-updated TIMESTAMP field in field array */
 
558
  uint32_t next_number_index;               /* autoincrement key number */
 
559
  uint32_t next_number_key_offset;          /* autoinc keypart offset in a key */
 
560
  uint32_t next_number_keypart;             /* autoinc keypart number in a key */
 
561
  uint32_t error, open_errno, errarg;       /* error from open_table_def() */
 
562
  uint32_t column_bitmap_size;
 
563
 
 
564
  uint8_t blob_ptr_size;                        /* 4 or 8 */
 
565
  bool db_low_byte_first;               /* Portable row format */
 
566
 
 
567
  bool name_lock;
 
568
  bool isNameLock() const
 
569
  {
 
570
    return name_lock;
 
571
  }
 
572
 
 
573
  bool replace_with_name_lock;
 
574
 
 
575
  bool waiting_on_cond;                 /* Protection against free */
 
576
  bool isWaitingOnCondition()
 
577
  {
 
578
    return waiting_on_cond;
 
579
  }
 
580
 
 
581
  /*
 
582
    Set of keys in use, implemented as a Bitmap.
 
583
    Excludes keys disabled by ALTER Table ... DISABLE KEYS.
 
584
  */
 
585
  key_map keys_in_use;
 
586
  key_map keys_for_keyread;
 
587
 
 
588
  /* 
 
589
    event_observers is a class containing all the event plugins that have 
 
590
    registered an interest in this table.
 
591
  */
 
592
  private:
 
593
  plugin::EventObserverList *event_observers;
 
594
  public:
 
595
  plugin::EventObserverList *getTableObservers() 
 
596
  { 
 
597
    return event_observers;
 
598
  }
 
599
  
 
600
  void setTableObservers(plugin::EventObserverList *observers) 
 
601
  { 
 
602
    event_observers= observers;
 
603
  }
 
604
  
 
605
  /*
 
606
    Set share's table cache key and update its db and table name appropriately.
 
607
 
 
608
    SYNOPSIS
 
609
    set_table_cache_key()
 
610
    key_buff    Buffer with already built table cache key to be
 
611
    referenced from share.
 
612
    key_length  Key length.
 
613
 
 
614
    NOTES
 
615
    Since 'key_buff' buffer will be referenced from share it should has same
 
616
    life-time as share itself.
 
617
    This method automatically ensures that TableShare::table_name/db have
 
618
    appropriate values by using table cache key as their source.
 
619
  */
 
620
 
 
621
  void set_table_cache_key(char *key_buff, uint32_t key_length, uint32_t db_length= 0, uint32_t table_name_length= 0)
 
622
  {
 
623
    table_cache_key.str= key_buff;
 
624
    table_cache_key.length= key_length;
 
625
    /*
 
626
      Let us use the fact that the key is "db/0/table_name/0" + optional
 
627
      part for temporary tables.
 
628
    */
 
629
    db.str=            table_cache_key.str;
 
630
    db.length=         db_length ? db_length : strlen(db.str);
 
631
    table_name.str=    db.str + db.length + 1;
 
632
    table_name.length= table_name_length ? table_name_length :strlen(table_name.str);
 
633
  }
 
634
 
 
635
  inline bool honor_global_locks()
 
636
  {
 
637
    return (table_category == TABLE_CATEGORY_USER);
 
638
  }
 
639
 
 
640
 
 
641
  /*
 
642
    Initialize share for temporary tables
 
643
 
 
644
    SYNOPSIS
 
645
    init()
 
646
    share       Share to fill
 
647
    key         Table_cache_key, as generated from create_table_def_key.
 
648
    must start with db name.
 
649
    key_length  Length of key
 
650
    table_name  Table name
 
651
    path        Path to table (possible in lower case)
 
652
 
 
653
    NOTES
 
654
    This is different from alloc_table_share() because temporary tables
 
655
    don't have to be shared between threads or put into the table def
 
656
    cache, so we can do some things notable simpler and faster
 
657
 
 
658
    If table is not put in session->temporary_tables (happens only when
 
659
    one uses OPEN TEMPORARY) then one can specify 'db' as key and
 
660
    use key_length= 0 as neither table_cache_key or key_length will be used).
 
661
  */
 
662
 
 
663
  void init()
 
664
  {
 
665
    init("", 0, "", "");
 
666
  }
 
667
 
 
668
  void init(const char *new_table_name,
 
669
            const char *new_path)
 
670
  {
 
671
    init("", 0, new_table_name, new_path);
 
672
  }
 
673
 
 
674
  void init(const char *key,
 
675
            uint32_t key_length, const char *new_table_name,
 
676
            const char *new_path)
 
677
  {
 
678
    memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
679
    table_category=         TABLE_CATEGORY_TEMPORARY;
 
680
    tmp_table=              message::Table::INTERNAL;
 
681
    db.str=                 (char*) key;
 
682
    db.length=           strlen(key);
 
683
    table_cache_key.str=    (char*) key;
 
684
    table_cache_key.length= key_length;
 
685
    table_name.str=         (char*) new_table_name;
 
686
    table_name.length=      strlen(new_table_name);
 
687
    path.str=               (char*) new_path;
 
688
    normalized_path.str=    (char*) new_path;
 
689
    path.length= normalized_path.length= strlen(new_path);
 
690
 
 
691
    return;
 
692
  }
 
693
 
 
694
  void open_table_error(int pass_error, int db_errno, int pass_errarg);
 
695
 
 
696
  /*
 
697
    Create a table cache key
 
698
 
 
699
    SYNOPSIS
 
700
    createKey()
 
701
    key                 Create key here (must be of size MAX_DBKEY_LENGTH)
 
702
    table_list          Table definition
 
703
 
 
704
    IMPLEMENTATION
 
705
    The table cache_key is created from:
 
706
    db_name + \0
 
707
    table_name + \0
 
708
 
 
709
    if the table is a tmp table, we add the following to make each tmp table
 
710
    unique on the slave:
 
711
 
 
712
    4 bytes for master thread id
 
713
    4 bytes pseudo thread id
 
714
 
 
715
    RETURN
 
716
    Length of key
 
717
  */
 
718
  static inline uint32_t createKey(char *key, const char *db_arg, const char *table_name_arg)
 
719
  {
 
720
    uint32_t key_length;
 
721
    char *key_pos= key;
 
722
 
 
723
    key_pos= strcpy(key_pos, db_arg) + strlen(db_arg);
 
724
    key_pos= strcpy(key_pos+1, table_name_arg) +
 
725
      strlen(table_name_arg);
 
726
    key_length= (uint32_t)(key_pos-key)+1;
 
727
 
 
728
    return key_length;
 
729
  }
 
730
 
 
731
  static inline uint32_t createKey(char *key, TableIdentifier &identifier)
 
732
  {
 
733
    uint32_t key_length;
 
734
    char *key_pos= key;
 
735
 
 
736
    key_pos= strcpy(key_pos, identifier.getSchemaName().c_str()) + identifier.getSchemaName().length();
 
737
    key_pos= strcpy(key_pos + 1, identifier.getTableName().c_str()) + identifier.getTableName().length();
 
738
    key_length= (uint32_t)(key_pos-key)+1;
 
739
 
 
740
    return key_length;
 
741
  }
 
742
 
 
743
  static void cacheStart(void);
 
744
  static void cacheStop(void);
 
745
  static void release(TableShare *share);
 
746
  static void release(const char *key, uint32_t key_length);
 
747
  static TableDefinitionCache &getCache();
 
748
  static TableShare *getShare(TableIdentifier &identifier);
 
749
  static TableShare *getShare(Session *session, 
 
750
                              char *key, uint32_t key_length, int *error);
 
751
 
 
752
  friend std::ostream& operator<<(std::ostream& output, const TableShare &share)
 
753
  {
 
754
    output << "TableShare:(";
 
755
    output <<  share.getSchemaName();
 
756
    output << ", ";
 
757
    output << share.getTableName();
 
758
    output << ", ";
 
759
    output << share.getTableTypeAsString();
 
760
    output << ", ";
 
761
    output << share.getPath();
 
762
    output << ")";
 
763
 
 
764
    return output;  // for multiple << operators.
 
765
  }
 
766
 
 
767
  bool newed;
 
768
 
 
769
  Field *make_field(unsigned char *ptr,
 
770
                    uint32_t field_length,
 
771
                    bool is_nullable,
 
772
                    unsigned char *null_pos,
 
773
                    unsigned char null_bit,
 
774
                    uint8_t decimals,
 
775
                    enum_field_types field_type,
 
776
                    const CHARSET_INFO * field_charset,
 
777
                    Field::utype unireg_check,
 
778
                    TYPELIB *interval,
 
779
                    const char *field_name);
 
780
 
 
781
  int open_table_def(Session& session, TableIdentifier &identifier);
 
782
 
 
783
  int open_table_from_share(Session *session, const char *alias,
 
784
                            uint32_t db_stat, uint32_t ha_open_flags,
 
785
                            Table &outparam);
 
786
  int parse_table_proto(Session& session, message::Table &table);
 
787
private:
 
788
  int inner_parse_table_proto(Session& session, message::Table &table);
 
789
};
 
790
 
 
791
} /* namespace drizzled */
 
792
 
 
793
#endif /* DRIZZLED_TABLE_SHARE_H */