~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_share.h

  • Committer: Stewart Smith
  • Date: 2008-11-21 16:06:07 UTC
  • mto: This revision was merged to the branch mainline in revision 593.
  • Revision ID: stewart@flamingspork.com-20081121160607-n6gdlt013spuo54r
remove mysql_frm_type
and fix engines to return correct value from delete_table when table doesn't exist.
(it should be ENOENT).

Also fix up some tests that manipulated frm files by hand. These tests are no longer valid and will need to be rewritten in the not too distant future.

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