~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_share.cc

  • Committer: Brian Aker
  • Date: 2009-08-04 06:21:17 UTC
  • mfrom: (1108.2.2 merge)
  • Revision ID: brian@gaz-20090804062117-fef8x6y3ydzrvab3
Merge Brian

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; i/dent-tabs-mode: nil; -*-
 
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) 2010 Brian Aker
5
 
 *  Copyright (C) 2009 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2009 Sun Microsystems
6
5
 *
7
6
 *  This program is free software; you can redistribute it and/or modify
8
7
 *  it under the terms of the GNU General Public License as published by
25
24
*/
26
25
 
27
26
/* Basic functions needed by many modules */
28
 
#include "config.h"
29
 
 
30
 
#include <pthread.h>
31
 
#include <float.h>
32
 
 
33
 
#include <sys/types.h>
34
 
#include <sys/stat.h>
35
 
#include <fcntl.h>
36
 
 
37
 
 
38
 
#include <cassert>
39
 
 
40
 
#include "drizzled/error.h"
41
 
#include "drizzled/gettext.h"
42
 
#include "drizzled/sql_base.h"
43
 
#include "drizzled/pthread_globals.h"
44
 
#include "drizzled/internal/my_pthread.h"
45
 
 
46
 
#include "drizzled/table.h"
47
 
#include "drizzled/table/shell.h"
48
 
 
49
 
#include "drizzled/session.h"
50
 
 
51
 
#include "drizzled/charset.h"
52
 
#include "drizzled/internal/m_string.h"
53
 
#include "drizzled/internal/my_sys.h"
54
 
 
55
 
#include "drizzled/item/string.h"
56
 
#include "drizzled/item/int.h"
57
 
#include "drizzled/item/decimal.h"
58
 
#include "drizzled/item/float.h"
59
 
#include "drizzled/item/null.h"
60
 
#include "drizzled/temporal.h"
61
 
 
62
 
#include "drizzled/field.h"
63
 
#include "drizzled/field/str.h"
64
 
#include "drizzled/field/num.h"
65
 
#include "drizzled/field/blob.h"
66
 
#include "drizzled/field/boolean.h"
67
 
#include "drizzled/field/enum.h"
68
 
#include "drizzled/field/null.h"
69
 
#include "drizzled/field/date.h"
70
 
#include "drizzled/field/decimal.h"
71
 
#include "drizzled/field/real.h"
72
 
#include "drizzled/field/double.h"
73
 
#include "drizzled/field/int32.h"
74
 
#include "drizzled/field/int64.h"
75
 
#include "drizzled/field/size.h"
76
 
#include "drizzled/field/num.h"
77
 
#include "drizzled/field/time.h"
78
 
#include "drizzled/field/epoch.h"
79
 
#include "drizzled/field/datetime.h"
80
 
#include "drizzled/field/microtime.h"
81
 
#include "drizzled/field/varstring.h"
82
 
#include "drizzled/field/uuid.h"
83
 
 
84
 
#include "drizzled/plugin/storage_engine.h"
85
 
 
86
 
#include "drizzled/definition/cache.h"
87
 
 
88
 
#include <drizzled/refresh_version.h>
 
27
#include <drizzled/server_includes.h>
 
28
#include <assert.h>
 
29
 
 
30
#include <drizzled/error.h>
 
31
#include <drizzled/gettext.h>
 
32
#include <drizzled/sql_base.h>
89
33
 
90
34
using namespace std;
91
35
 
92
 
namespace drizzled
93
 
{
94
 
 
95
 
extern size_t table_def_size;
96
 
 
97
 
 
98
 
static enum_field_types proto_field_type_to_drizzle_type(const message::Table::Field &field)
99
 
{
100
 
  switch(field.type())
101
 
  {
102
 
  case message::Table::Field::INTEGER:
103
 
    return DRIZZLE_TYPE_LONG;
104
 
 
105
 
  case message::Table::Field::DOUBLE:
106
 
    return DRIZZLE_TYPE_DOUBLE;
107
 
 
108
 
  case message::Table::Field::EPOCH:
109
 
    if (field.has_time_options() and field.time_options().microseconds())
110
 
      return DRIZZLE_TYPE_MICROTIME;
111
 
 
112
 
    return DRIZZLE_TYPE_TIMESTAMP;
113
 
 
114
 
  case message::Table::Field::BIGINT:
115
 
    return DRIZZLE_TYPE_LONGLONG;
116
 
 
117
 
  case message::Table::Field::DATETIME:
118
 
    return DRIZZLE_TYPE_DATETIME;
119
 
 
120
 
  case message::Table::Field::DATE:
121
 
    return DRIZZLE_TYPE_DATE;
122
 
 
123
 
  case message::Table::Field::VARCHAR:
124
 
    return DRIZZLE_TYPE_VARCHAR;
125
 
 
126
 
  case message::Table::Field::DECIMAL:
127
 
    return DRIZZLE_TYPE_DECIMAL;
128
 
 
129
 
  case message::Table::Field::ENUM:
130
 
    return DRIZZLE_TYPE_ENUM;
131
 
 
132
 
  case message::Table::Field::BLOB:
133
 
    return DRIZZLE_TYPE_BLOB;
134
 
 
135
 
  case message::Table::Field::UUID:
136
 
    return  DRIZZLE_TYPE_UUID;
137
 
 
138
 
  case message::Table::Field::BOOLEAN:
139
 
    return DRIZZLE_TYPE_BOOLEAN;
140
 
 
141
 
  case message::Table::Field::TIME:
142
 
    return DRIZZLE_TYPE_TIME;
143
 
  }
144
 
 
145
 
  abort();
146
 
}
147
 
 
148
 
static Item *default_value_item(enum_field_types field_type,
149
 
                                const CHARSET_INFO *charset,
150
 
                                bool default_null, const string *default_value,
151
 
                                const string *default_bin_value)
152
 
{
153
 
  Item *default_item= NULL;
154
 
  int error= 0;
155
 
 
156
 
  if (default_null)
157
 
  {
158
 
    return new Item_null();
159
 
  }
160
 
 
161
 
  switch(field_type)
162
 
  {
163
 
  case DRIZZLE_TYPE_LONG:
164
 
  case DRIZZLE_TYPE_LONGLONG:
165
 
    default_item= new Item_int(default_value->c_str(),
166
 
                               (int64_t) internal::my_strtoll10(default_value->c_str(),
167
 
                                                                NULL,
168
 
                                                                &error),
169
 
                               default_value->length());
170
 
    break;
171
 
  case DRIZZLE_TYPE_DOUBLE:
172
 
    default_item= new Item_float(default_value->c_str(),
173
 
                                 default_value->length());
174
 
    break;
175
 
  case DRIZZLE_TYPE_NULL:
176
 
    assert(0);
177
 
    abort();
178
 
  case DRIZZLE_TYPE_TIMESTAMP:
179
 
  case DRIZZLE_TYPE_DATETIME:
180
 
  case DRIZZLE_TYPE_TIME:
181
 
  case DRIZZLE_TYPE_DATE:
182
 
  case DRIZZLE_TYPE_ENUM:
183
 
  case DRIZZLE_TYPE_UUID:
184
 
  case DRIZZLE_TYPE_MICROTIME:
185
 
  case DRIZZLE_TYPE_BOOLEAN:
186
 
    default_item= new Item_string(default_value->c_str(),
187
 
                                  default_value->length(),
188
 
                                  system_charset_info);
189
 
    break;
190
 
  case DRIZZLE_TYPE_VARCHAR:
191
 
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
192
 
    if (charset==&my_charset_bin)
193
 
    {
194
 
      default_item= new Item_string(default_bin_value->c_str(),
195
 
                                    default_bin_value->length(),
196
 
                                    &my_charset_bin);
197
 
    }
198
 
    else
199
 
    {
200
 
      default_item= new Item_string(default_value->c_str(),
201
 
                                    default_value->length(),
202
 
                                    system_charset_info);
203
 
    }
204
 
    break;
205
 
  case DRIZZLE_TYPE_DECIMAL:
206
 
    default_item= new Item_decimal(default_value->c_str(),
207
 
                                   default_value->length(),
208
 
                                   system_charset_info);
209
 
    break;
210
 
  }
211
 
 
212
 
  return default_item;
213
 
}
214
 
 
215
 
 
216
 
 
217
 
/**
218
 
 * @todo
219
 
 *
220
 
 * Precache this stuff....
221
 
 */
222
 
bool TableShare::fieldInPrimaryKey(Field *in_field) const
223
 
{
224
 
  assert(getTableMessage());
225
 
 
226
 
  size_t num_indexes= getTableMessage()->indexes_size();
227
 
 
228
 
  for (size_t x= 0; x < num_indexes; ++x)
229
 
  {
230
 
    const message::Table::Index &index= getTableMessage()->indexes(x);
231
 
    if (index.is_primary())
232
 
    {
233
 
      size_t num_parts= index.index_part_size();
234
 
      for (size_t y= 0; y < num_parts; ++y)
235
 
      {
236
 
        if (index.index_part(y).fieldnr() == in_field->position())
237
 
          return true;
238
 
      }
239
 
    }
240
 
  }
241
 
  return false;
242
 
}
243
 
 
244
 
TableShare::TableShare(const identifier::Table::Type type_arg) :
245
 
  table_category(TABLE_UNKNOWN_CATEGORY),
246
 
  found_next_number_field(NULL),
247
 
  timestamp_field(NULL),
248
 
  key_info(NULL),
249
 
  mem_root(TABLE_ALLOC_BLOCK_SIZE),
250
 
  all_set(),
251
 
  db(NULL_LEX_STRING),
252
 
  table_name(NULL_LEX_STRING),
253
 
  path(NULL_LEX_STRING),
254
 
  normalized_path(NULL_LEX_STRING),
255
 
  block_size(0),
256
 
  version(0),
257
 
  timestamp_offset(0),
258
 
  reclength(0),
259
 
  stored_rec_length(0),
260
 
  max_rows(0),
261
 
  _table_message(NULL),
262
 
  storage_engine(NULL),
263
 
  tmp_table(type_arg),
264
 
  _ref_count(0),
265
 
  null_bytes(0),
266
 
  last_null_bit_pos(0),
267
 
  _field_size(0),
268
 
  rec_buff_length(0),
269
 
  keys(0),
270
 
  key_parts(0),
271
 
  max_key_length(0),
272
 
  max_unique_length(0),
273
 
  total_key_length(0),
274
 
  uniques(0),
275
 
  null_fields(0),
276
 
  blob_fields(0),
277
 
  has_variable_width(false),
278
 
  db_create_options(0),
279
 
  db_options_in_use(0),
280
 
  db_record_offset(0),
281
 
  rowid_field_offset(0),
282
 
  primary_key(MAX_KEY),
283
 
  next_number_index(0),
284
 
  next_number_key_offset(0),
285
 
  next_number_keypart(0),
286
 
  error(0),
287
 
  open_errno(0),
288
 
  errarg(0),
289
 
  blob_ptr_size(portable_sizeof_char_ptr),
290
 
  db_low_byte_first(false),
291
 
  keys_in_use(0),
292
 
  keys_for_keyread(0)
293
 
{
294
 
  if (type_arg == message::Table::INTERNAL)
295
 
  {
296
 
    identifier::Table::build_tmptable_filename(private_key_for_cache.vectorPtr());
297
 
    init(private_key_for_cache.vector(), private_key_for_cache.vector());
298
 
  }
299
 
  else
300
 
  {
301
 
    init("", "");
302
 
  }
303
 
}
304
 
 
305
 
TableShare::TableShare(const identifier::Table &identifier, const identifier::Table::Key &key) :// Used by placeholder
306
 
  table_category(TABLE_UNKNOWN_CATEGORY),
307
 
  found_next_number_field(NULL),
308
 
  timestamp_field(NULL),
309
 
  key_info(NULL),
310
 
  mem_root(TABLE_ALLOC_BLOCK_SIZE),
311
 
  table_charset(0),
312
 
  all_set(),
313
 
  db(NULL_LEX_STRING),
314
 
  table_name(NULL_LEX_STRING),
315
 
  path(NULL_LEX_STRING),
316
 
  normalized_path(NULL_LEX_STRING),
317
 
  block_size(0),
318
 
  version(0),
319
 
  timestamp_offset(0),
320
 
  reclength(0),
321
 
  stored_rec_length(0),
322
 
  max_rows(0),
323
 
  _table_message(NULL),
324
 
  storage_engine(NULL),
325
 
  tmp_table(message::Table::INTERNAL),
326
 
  _ref_count(0),
327
 
  null_bytes(0),
328
 
  last_null_bit_pos(0),
329
 
  _field_size(0),
330
 
  rec_buff_length(0),
331
 
  keys(0),
332
 
  key_parts(0),
333
 
  max_key_length(0),
334
 
  max_unique_length(0),
335
 
  total_key_length(0),
336
 
  uniques(0),
337
 
  null_fields(0),
338
 
  blob_fields(0),
339
 
  has_variable_width(false),
340
 
  db_create_options(0),
341
 
  db_options_in_use(0),
342
 
  db_record_offset(0),
343
 
  rowid_field_offset(0),
344
 
  primary_key(MAX_KEY),
345
 
  next_number_index(0),
346
 
  next_number_key_offset(0),
347
 
  next_number_keypart(0),
348
 
  error(0),
349
 
  open_errno(0),
350
 
  errarg(0),
351
 
  blob_ptr_size(portable_sizeof_char_ptr),
352
 
  db_low_byte_first(false),
353
 
  keys_in_use(0),
354
 
  keys_for_keyread(0)
355
 
{
356
 
  assert(identifier.getKey() == key);
357
 
 
358
 
  private_key_for_cache= key;
359
 
 
360
 
  table_category=         TABLE_CATEGORY_TEMPORARY;
361
 
  tmp_table=              message::Table::INTERNAL;
362
 
 
363
 
  db.str= const_cast<char *>(private_key_for_cache.vector());
364
 
  db.length= strlen(private_key_for_cache.vector());
365
 
 
366
 
  table_name.str= const_cast<char *>(private_key_for_cache.vector()) + strlen(private_key_for_cache.vector()) + 1;
367
 
  table_name.length= strlen(table_name.str);
368
 
  path.str= (char *)"";
369
 
  normalized_path.str= path.str;
370
 
  path.length= normalized_path.length= 0;
371
 
 
372
 
  std::string tb_name(identifier.getTableName());
373
 
  std::transform(tb_name.begin(), tb_name.end(), tb_name.begin(), ::tolower);
374
 
  assert(strcmp(tb_name.c_str(), table_name.str) == 0);
375
 
 
376
 
  assert(strcmp(identifier.getSchemaName().c_str(), db.str) == 0);
377
 
}
378
 
 
379
 
 
380
 
TableShare::TableShare(const identifier::Table &identifier) : // Just used during createTable()
381
 
  table_category(TABLE_UNKNOWN_CATEGORY),
382
 
  found_next_number_field(NULL),
383
 
  timestamp_field(NULL),
384
 
  key_info(NULL),
385
 
  mem_root(TABLE_ALLOC_BLOCK_SIZE),
386
 
  table_charset(0),
387
 
  all_set(),
388
 
  db(NULL_LEX_STRING),
389
 
  table_name(NULL_LEX_STRING),
390
 
  path(NULL_LEX_STRING),
391
 
  normalized_path(NULL_LEX_STRING),
392
 
  block_size(0),
393
 
  version(0),
394
 
  timestamp_offset(0),
395
 
  reclength(0),
396
 
  stored_rec_length(0),
397
 
  max_rows(0),
398
 
  _table_message(NULL),
399
 
  storage_engine(NULL),
400
 
  tmp_table(identifier.getType()),
401
 
  _ref_count(0),
402
 
  null_bytes(0),
403
 
  last_null_bit_pos(0),
404
 
  _field_size(0),
405
 
  rec_buff_length(0),
406
 
  keys(0),
407
 
  key_parts(0),
408
 
  max_key_length(0),
409
 
  max_unique_length(0),
410
 
  total_key_length(0),
411
 
  uniques(0),
412
 
  null_fields(0),
413
 
  blob_fields(0),
414
 
  has_variable_width(false),
415
 
  db_create_options(0),
416
 
  db_options_in_use(0),
417
 
  db_record_offset(0),
418
 
  rowid_field_offset(0),
419
 
  primary_key(MAX_KEY),
420
 
  next_number_index(0),
421
 
  next_number_key_offset(0),
422
 
  next_number_keypart(0),
423
 
  error(0),
424
 
  open_errno(0),
425
 
  errarg(0),
426
 
  blob_ptr_size(portable_sizeof_char_ptr),
427
 
  db_low_byte_first(false),
428
 
  keys_in_use(0),
429
 
  keys_for_keyread(0)
430
 
{
431
 
  private_key_for_cache= identifier.getKey();
432
 
  assert(identifier.getPath().size()); // Since we are doing a create table, this should be a positive value
433
 
  private_normalized_path.resize(identifier.getPath().size() + 1);
434
 
  memcpy(&private_normalized_path[0], identifier.getPath().c_str(), identifier.getPath().size());
435
 
 
436
 
  {
437
 
    table_category=         TABLE_CATEGORY_TEMPORARY;
438
 
    tmp_table=              message::Table::INTERNAL;
439
 
    db.str= const_cast<char *>(private_key_for_cache.vector());
440
 
    db.length= strlen(private_key_for_cache.vector());
441
 
    table_name.str= db.str + 1;
442
 
    table_name.length= strlen(table_name.str);
443
 
    path.str= &private_normalized_path[0];
444
 
    normalized_path.str= path.str;
445
 
    path.length= normalized_path.length= private_normalized_path.size();
446
 
  }
 
36
static HASH table_def_cache;
 
37
static pthread_mutex_t LOCK_table_share;
 
38
bool table_def_inited= false;
 
39
 
 
40
/*****************************************************************************
 
41
  Functions to handle table definition cach (TableShare)
 
42
 *****************************************************************************/
 
43
 
 
44
extern "C"
 
45
{
 
46
  unsigned char *table_def_key(const unsigned char *record,
 
47
                               size_t *length,
 
48
                               bool );
 
49
}
 
50
 
 
51
unsigned char *table_def_key(const unsigned char *record,
 
52
                             size_t *length,
 
53
                             bool )
 
54
{
 
55
  TableShare *entry=(TableShare*) record;
 
56
  *length= entry->table_cache_key.length;
 
57
  return (unsigned char*) entry->table_cache_key.str;
 
58
}
 
59
 
 
60
 
 
61
static void table_def_free_entry(TableShare *share)
 
62
{
 
63
  share->free_table_share();
 
64
}
 
65
 
 
66
 
 
67
bool TableShare::cacheStart(void)
 
68
{
 
69
  table_def_inited= true;
 
70
  pthread_mutex_init(&LOCK_table_share, MY_MUTEX_INIT_FAST);
 
71
 
 
72
  return hash_init(&table_def_cache, &my_charset_bin, (size_t)table_def_size,
 
73
                   0, 0, table_def_key,
 
74
                   (hash_free_key) table_def_free_entry, 0);
 
75
}
 
76
 
 
77
 
 
78
void TableShare::cacheStop(void)
 
79
{
 
80
  if (table_def_inited)
 
81
  {
 
82
    table_def_inited= 0;
 
83
    pthread_mutex_destroy(&LOCK_table_share);
 
84
    hash_free(&table_def_cache);
 
85
  }
 
86
}
 
87
 
 
88
 
 
89
uint32_t cached_table_definitions(void)
 
90
{
 
91
  return table_def_cache.records;
447
92
}
448
93
 
449
94
 
450
95
/*
451
 
  Used for shares that will go into the cache.
 
96
  Mark that we are not using table share anymore.
 
97
 
 
98
  SYNOPSIS
 
99
  release()
 
100
  share         Table share
 
101
 
 
102
  IMPLEMENTATION
 
103
  If ref_count goes to zero and (we have done a refresh or if we have
 
104
  already too many open table shares) then delete the definition.
452
105
*/
453
 
TableShare::TableShare(const identifier::Table::Type type_arg,
454
 
                       const identifier::Table &identifier,
455
 
                       char *path_arg,
456
 
                       uint32_t path_length_arg) :
457
 
  table_category(TABLE_UNKNOWN_CATEGORY),
458
 
  found_next_number_field(NULL),
459
 
  timestamp_field(NULL),
460
 
  key_info(NULL),
461
 
  mem_root(TABLE_ALLOC_BLOCK_SIZE),
462
 
  table_charset(0),
463
 
  all_set(),
464
 
  db(NULL_LEX_STRING),
465
 
  table_name(NULL_LEX_STRING),
466
 
  path(NULL_LEX_STRING),
467
 
  normalized_path(NULL_LEX_STRING),
468
 
  block_size(0),
469
 
  version(0),
470
 
  timestamp_offset(0),
471
 
  reclength(0),
472
 
  stored_rec_length(0),
473
 
  max_rows(0),
474
 
  _table_message(NULL),
475
 
  storage_engine(NULL),
476
 
  tmp_table(type_arg),
477
 
  _ref_count(0),
478
 
  null_bytes(0),
479
 
  last_null_bit_pos(0),
480
 
  _field_size(0),
481
 
  rec_buff_length(0),
482
 
  keys(0),
483
 
  key_parts(0),
484
 
  max_key_length(0),
485
 
  max_unique_length(0),
486
 
  total_key_length(0),
487
 
  uniques(0),
488
 
  null_fields(0),
489
 
  blob_fields(0),
490
 
  has_variable_width(false),
491
 
  db_create_options(0),
492
 
  db_options_in_use(0),
493
 
  db_record_offset(0),
494
 
  rowid_field_offset(0),
495
 
  primary_key(MAX_KEY),
496
 
  next_number_index(0),
497
 
  next_number_key_offset(0),
498
 
  next_number_keypart(0),
499
 
  error(0),
500
 
  open_errno(0),
501
 
  errarg(0),
502
 
  blob_ptr_size(portable_sizeof_char_ptr),
503
 
  db_low_byte_first(false),
504
 
  keys_in_use(0),
505
 
  keys_for_keyread(0)
506
 
{
507
 
  char *path_buff;
508
 
  std::string _path;
509
 
 
510
 
  private_key_for_cache= identifier.getKey();
511
 
  /*
512
 
    Let us use the fact that the key is "db/0/table_name/0" + optional
513
 
    part for temporary tables.
514
 
  */
515
 
  db.str= const_cast<char *>(private_key_for_cache.vector());
516
 
  db.length=         strlen(db.str);
517
 
  table_name.str=    db.str + db.length + 1;
518
 
  table_name.length= strlen(table_name.str);
519
 
 
520
 
  if (path_arg)
521
 
  {
522
 
    _path.append(path_arg, path_length_arg);
523
 
  }
524
 
  else
525
 
  {
526
 
    identifier::Table::build_table_filename(_path, db.str, table_name.str, false);
527
 
  }
528
 
 
529
 
  if ((path_buff= (char *)mem_root.alloc_root(_path.length() + 1)))
530
 
  {
531
 
    setPath(path_buff, _path.length());
532
 
    strcpy(path_buff, _path.c_str());
533
 
    setNormalizedPath(path_buff, _path.length());
534
 
 
535
 
    version= refresh_version;
536
 
  }
537
 
  else
538
 
  {
539
 
    assert(0); // We should throw here.
540
 
    abort();
541
 
  }
542
 
}
543
 
 
544
 
void TableShare::init(const char *new_table_name,
545
 
                      const char *new_path)
546
 
{
547
 
 
548
 
  table_category=         TABLE_CATEGORY_TEMPORARY;
549
 
  tmp_table=              message::Table::INTERNAL;
550
 
  db.str= (char *)"";
551
 
  db.length= 0;
552
 
  table_name.str=         (char*) new_table_name;
553
 
  table_name.length=      strlen(new_table_name);
554
 
  path.str=               (char*) new_path;
555
 
  normalized_path.str=    (char*) new_path;
556
 
  path.length= normalized_path.length= strlen(new_path);
557
 
}
558
 
 
559
 
TableShare::~TableShare() 
560
 
{
561
 
  storage_engine= NULL;
562
 
 
563
 
  mem_root.free_root(MYF(0));                 // Free's share
564
 
}
565
 
 
566
 
void TableShare::setIdentifier(const identifier::Table &identifier_arg)
567
 
{
568
 
  private_key_for_cache= identifier_arg.getKey();
569
 
 
570
 
  /*
571
 
    Let us use the fact that the key is "db/0/table_name/0" + optional
572
 
    part for temporary tables.
573
 
  */
574
 
  db.str= const_cast<char *>(private_key_for_cache.vector());
575
 
  db.length=         strlen(db.str);
576
 
  table_name.str=    db.str + db.length + 1;
577
 
  table_name.length= strlen(table_name.str);
578
 
 
579
 
  getTableMessage()->set_name(identifier_arg.getTableName());
580
 
  getTableMessage()->set_schema(identifier_arg.getSchemaName());
581
 
}
582
 
 
583
 
bool TableShare::parse_table_proto(Session& session, message::Table &table)
584
 
{
585
 
  drizzled::error_t local_error= EE_OK;
586
 
 
587
 
  if (! table.IsInitialized())
588
 
  {
589
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
590
 
             table.name().empty() ? " " :  table.name().c_str(),
591
 
             table.InitializationErrorString().c_str());
592
 
 
593
 
    return ER_CORRUPT_TABLE_DEFINITION;
594
 
  }
595
 
 
596
 
  setTableMessage(table);
597
 
 
598
 
  storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
599
 
  assert(storage_engine); // We use an assert() here because we should never get this far and still have no suitable engine.
600
 
 
601
 
  message::Table::TableOptions table_options;
602
 
 
603
 
  if (table.has_options())
604
 
    table_options= table.options();
605
 
 
606
 
  uint32_t local_db_create_options= 0;
607
 
 
608
 
  if (table_options.pack_record())
609
 
    local_db_create_options|= HA_OPTION_PACK_RECORD;
610
 
 
611
 
  /* local_db_create_options was stored as 2 bytes in FRM
612
 
    Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
613
 
  */
614
 
  db_create_options= (local_db_create_options & 0x0000FFFF);
615
 
  db_options_in_use= db_create_options;
616
 
 
617
 
  block_size= table_options.has_block_size() ?
618
 
    table_options.block_size() : 0;
619
 
 
620
 
  table_charset= get_charset(table_options.collation_id());
621
 
 
622
 
  if (not table_charset)
623
 
  {
624
 
    my_error(ER_CORRUPT_TABLE_DEFINITION_UNKNOWN_COLLATION, MYF(0),
625
 
             table_options.collation().c_str(),
626
 
             table.name().c_str());
627
 
 
628
 
    return ER_CORRUPT_TABLE_DEFINITION; // Historical
629
 
  }
630
 
 
631
 
  db_record_offset= 1;
632
 
 
633
 
  keys= table.indexes_size();
634
 
 
635
 
  key_parts= 0;
636
 
  for (int indx= 0; indx < table.indexes_size(); indx++)
637
 
    key_parts+= table.indexes(indx).index_part_size();
638
 
 
639
 
  key_info= (KeyInfo*) alloc_root( table.indexes_size() * sizeof(KeyInfo) +key_parts*sizeof(KeyPartInfo));
640
 
 
641
 
  KeyPartInfo *key_part;
642
 
 
643
 
  key_part= reinterpret_cast<KeyPartInfo*>
644
 
    (key_info+table.indexes_size());
645
 
 
646
 
 
647
 
  ulong *rec_per_key= (ulong*) alloc_root(sizeof(ulong*)*key_parts);
648
 
 
649
 
  KeyInfo* keyinfo= key_info;
650
 
  for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
651
 
  {
652
 
    message::Table::Index indx= table.indexes(keynr);
653
 
 
654
 
    keyinfo->table= 0;
655
 
    keyinfo->flags= 0;
656
 
 
657
 
    if (indx.is_unique())
658
 
      keyinfo->flags|= HA_NOSAME;
659
 
 
660
 
    if (indx.has_options())
661
 
    {
662
 
      message::Table::Index::Options indx_options= indx.options();
663
 
      if (indx_options.pack_key())
664
 
        keyinfo->flags|= HA_PACK_KEY;
665
 
 
666
 
      if (indx_options.var_length_key())
667
 
        keyinfo->flags|= HA_VAR_LENGTH_PART;
668
 
 
669
 
      if (indx_options.null_part_key())
670
 
        keyinfo->flags|= HA_NULL_PART_KEY;
671
 
 
672
 
      if (indx_options.binary_pack_key())
673
 
        keyinfo->flags|= HA_BINARY_PACK_KEY;
674
 
 
675
 
      if (indx_options.has_partial_segments())
676
 
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
677
 
 
678
 
      if (indx_options.auto_generated_key())
679
 
        keyinfo->flags|= HA_GENERATED_KEY;
680
 
 
681
 
      if (indx_options.has_key_block_size())
682
 
      {
683
 
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
684
 
        keyinfo->block_size= indx_options.key_block_size();
685
 
      }
686
 
      else
687
 
      {
688
 
        keyinfo->block_size= 0;
689
 
      }
690
 
    }
691
 
 
692
 
    switch (indx.type())
693
 
    {
694
 
    case message::Table::Index::UNKNOWN_INDEX:
695
 
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
696
 
      break;
697
 
    case message::Table::Index::BTREE:
698
 
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
699
 
      break;
700
 
    case message::Table::Index::HASH:
701
 
      keyinfo->algorithm= HA_KEY_ALG_HASH;
702
 
      break;
703
 
 
704
 
    default:
705
 
      /* TODO: suitable warning ? */
706
 
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
707
 
      break;
708
 
    }
709
 
 
710
 
    keyinfo->key_length= indx.key_length();
711
 
 
712
 
    keyinfo->key_parts= indx.index_part_size();
713
 
 
714
 
    keyinfo->key_part= key_part;
715
 
    keyinfo->rec_per_key= rec_per_key;
716
 
 
717
 
    for (unsigned int partnr= 0;
718
 
         partnr < keyinfo->key_parts;
719
 
         partnr++, key_part++)
720
 
    {
721
 
      message::Table::Index::IndexPart part;
722
 
      part= indx.index_part(partnr);
723
 
 
724
 
      *rec_per_key++= 0;
725
 
 
726
 
      key_part->field= NULL;
727
 
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
728
 
      key_part->null_bit= 0;
729
 
      /* key_part->null_offset is only set if null_bit (see later) */
730
 
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
731
 
      /* key_part->type ???? */
732
 
      key_part->key_part_flag= 0;
733
 
      if (part.has_in_reverse_order())
734
 
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
735
 
 
736
 
      key_part->length= part.compare_length();
737
 
 
738
 
      int mbmaxlen= 1;
739
 
 
740
 
      if (table.field(part.fieldnr()).type() == message::Table::Field::VARCHAR
741
 
          || table.field(part.fieldnr()).type() == message::Table::Field::BLOB)
742
 
      {
743
 
        uint32_t collation_id;
744
 
 
745
 
        if (table.field(part.fieldnr()).string_options().has_collation_id())
746
 
          collation_id= table.field(part.fieldnr()).string_options().collation_id();
747
 
        else
748
 
          collation_id= table.options().collation_id();
749
 
 
750
 
        const CHARSET_INFO *cs= get_charset(collation_id);
751
 
 
752
 
        mbmaxlen= cs->mbmaxlen;
753
 
      }
754
 
      key_part->length*= mbmaxlen;
755
 
 
756
 
      key_part->store_length= key_part->length;
757
 
 
758
 
      /* key_part->offset is set later */
759
 
      key_part->key_type= 0;
760
 
    }
761
 
 
762
 
    if (! indx.has_comment())
763
 
    {
764
 
      keyinfo->comment.length= 0;
765
 
      keyinfo->comment.str= NULL;
766
 
    }
767
 
    else
768
 
    {
769
 
      keyinfo->flags|= HA_USES_COMMENT;
770
 
      keyinfo->comment.length= indx.comment().length();
771
 
      keyinfo->comment.str= strmake_root(indx.comment().c_str(), keyinfo->comment.length);
772
 
    }
773
 
 
774
 
    keyinfo->name= strmake_root(indx.name().c_str(), indx.name().length());
775
 
 
776
 
    addKeyName(string(keyinfo->name, indx.name().length()));
777
 
  }
778
 
 
779
 
  keys_for_keyread.reset();
780
 
  set_prefix(keys_in_use, keys);
781
 
 
782
 
  _field_size= table.field_size();
783
 
 
784
 
  setFields(_field_size + 1);
785
 
  _fields[_field_size]= NULL;
786
 
 
787
 
  uint32_t local_null_fields= 0;
788
 
  reclength= 0;
789
 
 
790
 
  std::vector<uint32_t> field_offsets;
791
 
  std::vector<uint32_t> field_pack_length;
792
 
 
793
 
  field_offsets.resize(_field_size);
794
 
  field_pack_length.resize(_field_size);
795
 
 
796
 
  uint32_t interval_count= 0;
797
 
  uint32_t interval_parts= 0;
798
 
 
799
 
  uint32_t stored_columns_reclength= 0;
800
 
 
801
 
  for (unsigned int fieldnr= 0; fieldnr < _field_size; fieldnr++)
802
 
  {
803
 
    message::Table::Field pfield= table.field(fieldnr);
804
 
    if (pfield.constraints().is_nullable()) // Historical reference
805
 
    {
806
 
      local_null_fields++;
807
 
    }
808
 
    else if (not pfield.constraints().is_notnull())
809
 
    {
810
 
      local_null_fields++;
811
 
    }
812
 
 
813
 
    enum_field_types drizzle_field_type= proto_field_type_to_drizzle_type(pfield);
814
 
 
815
 
    field_offsets[fieldnr]= stored_columns_reclength;
816
 
 
817
 
    /* the below switch is very similar to
818
 
      CreateField::create_length_to_internal_length in field.cc
819
 
      (which should one day be replace by just this code)
820
 
    */
821
 
    switch(drizzle_field_type)
822
 
    {
823
 
    case DRIZZLE_TYPE_BLOB:
824
 
    case DRIZZLE_TYPE_VARCHAR:
825
 
      {
826
 
        message::Table::Field::StringFieldOptions field_options= pfield.string_options();
827
 
 
828
 
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id() ?
829
 
                                            field_options.collation_id() : 0);
830
 
 
831
 
        if (! cs)
832
 
          cs= default_charset_info;
833
 
 
834
 
        field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type,
835
 
                                                     field_options.length() * cs->mbmaxlen);
836
 
      }
837
 
      break;
838
 
    case DRIZZLE_TYPE_ENUM:
839
 
      {
840
 
        message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
841
 
 
842
 
        field_pack_length[fieldnr]= 4;
843
 
 
844
 
        interval_count++;
845
 
        interval_parts+= field_options.field_value_size();
846
 
      }
847
 
      break;
848
 
    case DRIZZLE_TYPE_DECIMAL:
849
 
      {
850
 
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
851
 
 
852
 
        field_pack_length[fieldnr]= class_decimal_get_binary_size(fo.precision(), fo.scale());
853
 
      }
854
 
      break;
855
 
    default:
856
 
      /* Zero is okay here as length is fixed for other types. */
857
 
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
858
 
    }
859
 
 
860
 
    reclength+= field_pack_length[fieldnr];
861
 
    stored_columns_reclength+= field_pack_length[fieldnr];
862
 
  }
863
 
 
864
 
  /* data_offset added to stored_rec_length later */
865
 
  stored_rec_length= stored_columns_reclength;
866
 
 
867
 
  null_fields= local_null_fields;
868
 
 
869
 
  ulong null_bits= local_null_fields;
870
 
  if (! table_options.pack_record())
871
 
    null_bits++;
872
 
  ulong data_offset= (null_bits + 7)/8;
873
 
 
874
 
 
875
 
  reclength+= data_offset;
876
 
  stored_rec_length+= data_offset;
877
 
 
878
 
  ulong local_rec_buff_length;
879
 
 
880
 
  local_rec_buff_length= ALIGN_SIZE(reclength + 1);
881
 
  rec_buff_length= local_rec_buff_length;
882
 
 
883
 
  resizeDefaultValues(local_rec_buff_length);
884
 
  unsigned char* record= getDefaultValues();
885
 
  int null_count= 0;
886
 
 
887
 
  if (! table_options.pack_record())
888
 
  {
889
 
    null_count++; // one bit for delete mark.
890
 
    *record|= 1;
891
 
  }
892
 
 
893
 
 
894
 
  intervals.resize(interval_count);
895
 
 
896
 
  /* Now fix the TYPELIBs for the intervals (enum values)
897
 
    and field names.
898
 
  */
899
 
 
900
 
  uint32_t interval_nr= 0;
901
 
 
902
 
  for (unsigned int fieldnr= 0; fieldnr < _field_size; fieldnr++)
903
 
  {
904
 
    message::Table::Field pfield= table.field(fieldnr);
905
 
 
906
 
    /* enum typelibs */
907
 
    if (pfield.type() != message::Table::Field::ENUM)
908
 
      continue;
909
 
 
910
 
    message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
911
 
 
912
 
    if (field_options.field_value_size() > Field_enum::max_supported_elements)
913
 
    {
914
 
      my_error(ER_CORRUPT_TABLE_DEFINITION_ENUM, MYF(0), table.name().c_str());
915
 
 
916
 
      return ER_CORRUPT_TABLE_DEFINITION_ENUM; // Historical
917
 
    }
918
 
 
919
 
 
920
 
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id() ?
921
 
                                             field_options.collation_id() : 0);
922
 
 
923
 
    if (! charset)
924
 
      charset= default_charset_info;
925
 
 
926
 
    TYPELIB *t= (&intervals[interval_nr]);
927
 
 
928
 
    t->type_names= (const char**)alloc_root((field_options.field_value_size() + 1) * sizeof(char*));
929
 
 
930
 
    t->type_lengths= (unsigned int*) alloc_root((field_options.field_value_size() + 1) * sizeof(unsigned int));
931
 
 
932
 
    t->type_names[field_options.field_value_size()]= NULL;
933
 
    t->type_lengths[field_options.field_value_size()]= 0;
934
 
 
935
 
    t->count= field_options.field_value_size();
936
 
    t->name= NULL;
937
 
 
938
 
    for (int n= 0; n < field_options.field_value_size(); n++)
939
 
    {
940
 
      t->type_names[n]= strmake_root(field_options.field_value(n).c_str(), field_options.field_value(n).length());
941
 
 
942
 
      /* 
943
 
       * Go ask the charset what the length is as for "" length=1
944
 
       * and there's stripping spaces or some other crack going on.
945
 
     */
946
 
      uint32_t lengthsp;
947
 
      lengthsp= charset->cset->lengthsp(charset,
948
 
                                        t->type_names[n],
949
 
                                        field_options.field_value(n).length());
950
 
      t->type_lengths[n]= lengthsp;
951
 
    }
952
 
    interval_nr++;
953
 
  }
954
 
 
955
 
 
956
 
  /* and read the fields */
957
 
  interval_nr= 0;
958
 
 
959
 
  bool use_hash= _field_size >= MAX_FIELDS_BEFORE_HASH;
960
 
 
961
 
  unsigned char* null_pos= getDefaultValues();
962
 
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
963
 
 
964
 
  for (unsigned int fieldnr= 0; fieldnr < _field_size; fieldnr++)
965
 
  {
966
 
    message::Table::Field pfield= table.field(fieldnr);
967
 
 
968
 
    Field::utype unireg_type= Field::NONE;
969
 
 
970
 
    if (pfield.has_numeric_options() &&
971
 
        pfield.numeric_options().is_autoincrement())
972
 
    {
973
 
      unireg_type= Field::NEXT_NUMBER;
974
 
    }
975
 
 
976
 
    if (pfield.has_options() &&
977
 
        pfield.options().has_default_expression() &&
978
 
        pfield.options().default_expression().compare("CURRENT_TIMESTAMP") == 0)
979
 
    {
980
 
      if (pfield.options().has_update_expression() &&
981
 
          pfield.options().update_expression().compare("CURRENT_TIMESTAMP") == 0)
982
 
      {
983
 
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
984
 
      }
985
 
      else if (! pfield.options().has_update_expression())
986
 
      {
987
 
        unireg_type= Field::TIMESTAMP_DN_FIELD;
988
 
      }
989
 
      else
990
 
      {
991
 
        assert(0); // Invalid update value.
992
 
        abort();
993
 
      }
994
 
    }
995
 
    else if (pfield.has_options() &&
996
 
             pfield.options().has_update_expression() &&
997
 
             pfield.options().update_expression().compare("CURRENT_TIMESTAMP") == 0)
998
 
    {
999
 
      unireg_type= Field::TIMESTAMP_UN_FIELD;
1000
 
    }
1001
 
 
1002
 
    LEX_STRING comment;
1003
 
    if (!pfield.has_comment())
1004
 
    {
1005
 
      comment.str= (char*)"";
1006
 
      comment.length= 0;
1007
 
    }
1008
 
    else
1009
 
    {
1010
 
      size_t len= pfield.comment().length();
1011
 
      const char* str= pfield.comment().c_str();
1012
 
 
1013
 
      comment.str= strmake_root(str, len);
1014
 
      comment.length= len;
1015
 
    }
1016
 
 
1017
 
    enum_field_types field_type;
1018
 
 
1019
 
    field_type= proto_field_type_to_drizzle_type(pfield);
1020
 
 
1021
 
    const CHARSET_INFO *charset= &my_charset_bin;
1022
 
 
1023
 
    if (field_type == DRIZZLE_TYPE_BLOB ||
1024
 
        field_type == DRIZZLE_TYPE_VARCHAR)
1025
 
    {
1026
 
      message::Table::Field::StringFieldOptions field_options= pfield.string_options();
1027
 
 
1028
 
      charset= get_charset(field_options.has_collation_id() ?
1029
 
                           field_options.collation_id() : 0);
1030
 
 
1031
 
      if (! charset)
1032
 
        charset= default_charset_info;
1033
 
    }
1034
 
 
1035
 
    if (field_type == DRIZZLE_TYPE_ENUM)
1036
 
    {
1037
 
      message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
1038
 
 
1039
 
      charset= get_charset(field_options.has_collation_id()?
1040
 
                           field_options.collation_id() : 0);
1041
 
 
1042
 
      if (! charset)
1043
 
        charset= default_charset_info;
1044
 
    }
1045
 
 
1046
 
    uint8_t decimals= 0;
1047
 
    if (field_type == DRIZZLE_TYPE_DECIMAL
1048
 
        || field_type == DRIZZLE_TYPE_DOUBLE)
1049
 
    {
1050
 
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
1051
 
 
1052
 
      if (! pfield.has_numeric_options() || ! fo.has_scale())
1053
 
      {
1054
 
        /*
1055
 
          We don't write the default to table proto so
1056
 
          if no decimals specified for DOUBLE, we use the default.
1057
 
        */
1058
 
        decimals= NOT_FIXED_DEC;
1059
 
      }
1060
 
      else
1061
 
      {
1062
 
        if (fo.scale() > DECIMAL_MAX_SCALE)
1063
 
        {
1064
 
          local_error= ER_NOT_FORM_FILE;
1065
 
 
1066
 
          return true;
1067
 
        }
1068
 
        decimals= static_cast<uint8_t>(fo.scale());
1069
 
      }
1070
 
    }
1071
 
 
1072
 
    Item *default_value= NULL;
1073
 
 
1074
 
    if (pfield.options().has_default_value() ||
1075
 
        pfield.options().default_null()  ||
1076
 
        pfield.options().has_default_bin_value())
1077
 
    {
1078
 
      default_value= default_value_item(field_type,
1079
 
                                        charset,
1080
 
                                        pfield.options().default_null(),
1081
 
                                        &pfield.options().default_value(),
1082
 
                                        &pfield.options().default_bin_value());
1083
 
    }
1084
 
 
1085
 
 
1086
 
    uint32_t field_length= 0; //Assignment is for compiler complaint.
1087
 
 
1088
 
    // We set field_length in this loop.
1089
 
    switch (field_type)
1090
 
    {
1091
 
    case DRIZZLE_TYPE_BLOB:
1092
 
    case DRIZZLE_TYPE_VARCHAR:
1093
 
      {
1094
 
        message::Table::Field::StringFieldOptions field_options= pfield.string_options();
1095
 
 
1096
 
        charset= get_charset(field_options.has_collation_id() ?
1097
 
                             field_options.collation_id() : 0);
1098
 
 
1099
 
        if (! charset)
1100
 
          charset= default_charset_info;
1101
 
 
1102
 
        field_length= field_options.length() * charset->mbmaxlen;
1103
 
      }
1104
 
      break;
1105
 
    case DRIZZLE_TYPE_DOUBLE:
1106
 
      {
1107
 
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
1108
 
        if (!fo.has_precision() && !fo.has_scale())
1109
 
        {
1110
 
          field_length= DBL_DIG+7;
1111
 
        }
1112
 
        else
1113
 
        {
1114
 
          field_length= fo.precision();
1115
 
        }
1116
 
        if (field_length < decimals &&
1117
 
            decimals != NOT_FIXED_DEC)
1118
 
        {
1119
 
          my_error(ER_M_BIGGER_THAN_D, MYF(0), pfield.name().c_str());
1120
 
          local_error= ER_M_BIGGER_THAN_D;
1121
 
          return true;
1122
 
        }
1123
 
        break;
1124
 
      }
1125
 
    case DRIZZLE_TYPE_DECIMAL:
1126
 
      {
1127
 
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
1128
 
 
1129
 
        field_length= class_decimal_precision_to_length(fo.precision(), fo.scale(),
1130
 
                                                     false);
1131
 
        break;
1132
 
      }
1133
 
    case DRIZZLE_TYPE_DATETIME:
1134
 
      field_length= DateTime::MAX_STRING_LENGTH;
1135
 
      break;
1136
 
    case DRIZZLE_TYPE_DATE:
1137
 
      field_length= Date::MAX_STRING_LENGTH;
1138
 
      break;
1139
 
    case DRIZZLE_TYPE_ENUM:
1140
 
      {
1141
 
        field_length= 0;
1142
 
 
1143
 
        message::Table::Field::EnumerationValues fo= pfield.enumeration_values();
1144
 
 
1145
 
        for (int valnr= 0; valnr < fo.field_value_size(); valnr++)
1146
 
        {
1147
 
          if (fo.field_value(valnr).length() > field_length)
1148
 
          {
1149
 
            field_length= charset->cset->numchars(charset,
1150
 
                                                  fo.field_value(valnr).c_str(),
1151
 
                                                  fo.field_value(valnr).c_str()
1152
 
                                                  + fo.field_value(valnr).length())
1153
 
              * charset->mbmaxlen;
1154
 
          }
1155
 
        }
1156
 
      }
1157
 
      break;
1158
 
    case DRIZZLE_TYPE_LONG:
1159
 
      {
1160
 
        uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
1161
 
        field_length= MAX_INT_WIDTH+sign_len;
1162
 
      }
1163
 
      break;
1164
 
    case DRIZZLE_TYPE_LONGLONG:
1165
 
      {
1166
 
        uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
1167
 
        field_length= MAX_BIGINT_WIDTH+sign_len;
1168
 
      }
1169
 
      break;
1170
 
    case DRIZZLE_TYPE_UUID:
1171
 
      field_length= field::Uuid::max_string_length();
1172
 
      break;
1173
 
    case DRIZZLE_TYPE_BOOLEAN:
1174
 
      field_length= field::Boolean::max_string_length();
1175
 
      break;
1176
 
    case DRIZZLE_TYPE_MICROTIME:
1177
 
      field_length= field::Microtime::max_string_length();
1178
 
      break;
1179
 
    case DRIZZLE_TYPE_TIMESTAMP:
1180
 
      field_length= field::Epoch::max_string_length();
1181
 
      break;
1182
 
    case DRIZZLE_TYPE_TIME:
1183
 
      field_length= field::Time::max_string_length();
1184
 
      break;
1185
 
    case DRIZZLE_TYPE_NULL:
1186
 
      abort(); // Programming error
1187
 
    }
1188
 
 
1189
 
    bool is_not_null= false;
1190
 
 
1191
 
    if (not pfield.constraints().is_nullable())
1192
 
    {
1193
 
      is_not_null= true;
1194
 
    }
1195
 
    else if (pfield.constraints().is_notnull())
1196
 
    {
1197
 
      is_not_null= true;
1198
 
    }
1199
 
 
1200
 
    Field* f= make_field(pfield,
1201
 
                         record + field_offsets[fieldnr] + data_offset,
1202
 
                         field_length,
1203
 
                         not is_not_null,
1204
 
                         null_pos,
1205
 
                         null_bit_pos,
1206
 
                         decimals,
1207
 
                         field_type,
1208
 
                         charset,
1209
 
                         MTYP_TYPENR(unireg_type),
1210
 
                         ((field_type == DRIZZLE_TYPE_ENUM) ?  &intervals[interval_nr++] : (TYPELIB*) 0),
1211
 
                         getTableMessage()->field(fieldnr).name().c_str());
1212
 
 
1213
 
    _fields[fieldnr]= f;
1214
 
 
1215
 
    // Insert post make_field code here.
1216
 
    switch (field_type)
1217
 
    {
1218
 
    case DRIZZLE_TYPE_BLOB:
1219
 
    case DRIZZLE_TYPE_VARCHAR:
1220
 
    case DRIZZLE_TYPE_DOUBLE:
1221
 
    case DRIZZLE_TYPE_DECIMAL:
1222
 
    case DRIZZLE_TYPE_TIMESTAMP:
1223
 
    case DRIZZLE_TYPE_TIME:
1224
 
    case DRIZZLE_TYPE_DATETIME:
1225
 
    case DRIZZLE_TYPE_MICROTIME:
1226
 
    case DRIZZLE_TYPE_DATE:
1227
 
    case DRIZZLE_TYPE_ENUM:
1228
 
    case DRIZZLE_TYPE_LONG:
1229
 
    case DRIZZLE_TYPE_LONGLONG:
1230
 
    case DRIZZLE_TYPE_NULL:
1231
 
    case DRIZZLE_TYPE_UUID:
1232
 
    case DRIZZLE_TYPE_BOOLEAN:
1233
 
      break;
1234
 
    }
1235
 
 
1236
 
    // This needs to go, we should be setting the "use" on the field so that
1237
 
    // it does not reference the share/table.
1238
 
    table::Shell temp_table(*this); /* Use this so that BLOB DEFAULT '' works */
1239
 
    temp_table.in_use= &session;
1240
 
 
1241
 
    f->init(&temp_table); /* blob default values need table obj */
1242
 
 
1243
 
    if (! (f->flags & NOT_NULL_FLAG))
1244
 
    {
1245
 
      *f->null_ptr|= f->null_bit;
1246
 
      if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
1247
 
        null_pos++;
1248
 
      null_count++;
1249
 
    }
1250
 
 
1251
 
    if (default_value)
1252
 
    {
1253
 
      enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
1254
 
      session.count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
1255
 
      int res= default_value->save_in_field(f, 1);
1256
 
      session.count_cuted_fields= old_count_cuted_fields;
1257
 
      if (res != 0 && res != 3) /* @TODO Huh? */
1258
 
      {
1259
 
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
1260
 
        local_error= ER_INVALID_DEFAULT;
1261
 
 
1262
 
        return true;
1263
 
      }
1264
 
    }
1265
 
    else if (f->real_type() == DRIZZLE_TYPE_ENUM && (f->flags & NOT_NULL_FLAG))
1266
 
    {
1267
 
      f->set_notnull();
1268
 
      f->store((int64_t) 1, true);
1269
 
    }
1270
 
    else
1271
 
    {
1272
 
      f->reset();
1273
 
    }
1274
 
 
1275
 
    /* hack to undo f->init() */
1276
 
    f->setTable(NULL);
1277
 
    f->orig_table= NULL;
1278
 
 
1279
 
    f->setPosition(fieldnr);
1280
 
    f->comment= comment;
1281
 
    if (not default_value &&
1282
 
        not (f->unireg_check==Field::NEXT_NUMBER) &&
1283
 
        (f->flags & NOT_NULL_FLAG) &&
1284
 
        (not f->is_timestamp()))
1285
 
    {
1286
 
      f->flags|= NO_DEFAULT_VALUE_FLAG;
1287
 
    }
1288
 
 
1289
 
    if (f->unireg_check == Field::NEXT_NUMBER)
1290
 
      found_next_number_field= &(_fields[fieldnr]);
1291
 
 
1292
 
    if (use_hash) /* supposedly this never fails... but comments lie */
1293
 
    {
1294
 
      const char *local_field_name= _fields[fieldnr]->field_name;
1295
 
      name_hash.insert(make_pair(local_field_name, &(_fields[fieldnr])));
1296
 
    }
1297
 
  }
1298
 
 
1299
 
  keyinfo= key_info;
1300
 
  for (unsigned int keynr= 0; keynr < keys; keynr++, keyinfo++)
1301
 
  {
1302
 
    key_part= keyinfo->key_part;
1303
 
 
1304
 
    for (unsigned int partnr= 0;
1305
 
         partnr < keyinfo->key_parts;
1306
 
         partnr++, key_part++)
1307
 
    {
1308
 
      /* 
1309
 
       * Fix up key_part->offset by adding data_offset.
1310
 
       * We really should compute offset as well.
1311
 
       * But at least this way we are a little better.
1312
 
     */
1313
 
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
1314
 
    }
1315
 
  }
1316
 
 
1317
 
  /*
1318
 
    We need to set the unused bits to 1. If the number of bits is a multiple
1319
 
    of 8 there are no unused bits.
1320
 
  */
1321
 
  if (null_count & 7)
1322
 
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1323
 
 
1324
 
  null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
1325
 
 
1326
 
  last_null_bit_pos= null_bit_pos;
1327
 
 
1328
 
  /* Fix key stuff */
1329
 
  if (key_parts)
1330
 
  {
1331
 
    uint32_t local_primary_key= 0;
1332
 
    doesKeyNameExist("PRIMARY", local_primary_key);
1333
 
 
1334
 
    keyinfo= key_info;
1335
 
    key_part= keyinfo->key_part;
1336
 
 
1337
 
    for (uint32_t key= 0; key < keys; key++,keyinfo++)
1338
 
    {
1339
 
      uint32_t usable_parts= 0;
1340
 
 
1341
 
      if (local_primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1342
 
      {
1343
 
        /*
1344
 
          If the UNIQUE key doesn't have NULL columns and is not a part key
1345
 
          declare this as a primary key.
1346
 
        */
1347
 
        local_primary_key=key;
1348
 
        for (uint32_t i= 0; i < keyinfo->key_parts; i++)
1349
 
        {
1350
 
          uint32_t fieldnr= key_part[i].fieldnr;
1351
 
          if (not fieldnr ||
1352
 
              _fields[fieldnr-1]->null_ptr ||
1353
 
              _fields[fieldnr-1]->key_length() != key_part[i].length)
1354
 
          {
1355
 
            local_primary_key= MAX_KEY; // Can't be used
1356
 
            break;
1357
 
          }
1358
 
        }
1359
 
      }
1360
 
 
1361
 
      for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
1362
 
      {
1363
 
        Field *local_field;
1364
 
        if (! key_part->fieldnr)
1365
 
        {
1366
 
          return ENOMEM;
1367
 
        }
1368
 
        local_field= key_part->field= _fields[key_part->fieldnr-1];
1369
 
        key_part->type= local_field->key_type();
1370
 
        if (local_field->null_ptr)
1371
 
        {
1372
 
          key_part->null_offset=(uint32_t) ((unsigned char*) local_field->null_ptr - getDefaultValues());
1373
 
          key_part->null_bit= local_field->null_bit;
1374
 
          key_part->store_length+=HA_KEY_NULL_LENGTH;
1375
 
          keyinfo->flags|=HA_NULL_PART_KEY;
1376
 
          keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1377
 
          keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1378
 
        }
1379
 
        if (local_field->type() == DRIZZLE_TYPE_BLOB ||
1380
 
            local_field->real_type() == DRIZZLE_TYPE_VARCHAR)
1381
 
        {
1382
 
          if (local_field->type() == DRIZZLE_TYPE_BLOB)
1383
 
            key_part->key_part_flag|= HA_BLOB_PART;
1384
 
          else
1385
 
            key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1386
 
          keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1387
 
          key_part->store_length+=HA_KEY_BLOB_LENGTH;
1388
 
          keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1389
 
        }
1390
 
        if (i == 0 && key != local_primary_key)
1391
 
          local_field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1392
 
                                  (keyinfo->key_parts == 1)) ?
1393
 
                                 UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1394
 
        if (i == 0)
1395
 
          local_field->key_start.set(key);
1396
 
        if (local_field->key_length() == key_part->length &&
1397
 
            !(local_field->flags & BLOB_FLAG))
1398
 
        {
1399
 
          enum ha_key_alg algo= key_info[key].algorithm;
1400
 
          if (db_type()->index_flags(algo) & HA_KEYREAD_ONLY)
1401
 
          {
1402
 
            keys_for_keyread.set(key);
1403
 
            local_field->part_of_key.set(key);
1404
 
            local_field->part_of_key_not_clustered.set(key);
1405
 
          }
1406
 
          if (db_type()->index_flags(algo) & HA_READ_ORDER)
1407
 
            local_field->part_of_sortkey.set(key);
1408
 
        }
1409
 
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1410
 
            usable_parts == i)
1411
 
          usable_parts++;                       // For FILESORT
1412
 
        local_field->flags|= PART_KEY_FLAG;
1413
 
        if (key == local_primary_key)
1414
 
        {
1415
 
          local_field->flags|= PRI_KEY_FLAG;
1416
 
          /*
1417
 
            If this field is part of the primary key and all keys contains
1418
 
            the primary key, then we can use any key to find this column
1419
 
          */
1420
 
          if (storage_engine->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX))
1421
 
          {
1422
 
            local_field->part_of_key= keys_in_use;
1423
 
            if (local_field->part_of_sortkey.test(key))
1424
 
              local_field->part_of_sortkey= keys_in_use;
1425
 
          }
1426
 
        }
1427
 
        if (local_field->key_length() != key_part->length)
1428
 
        {
1429
 
          key_part->key_part_flag|= HA_PART_KEY_SEG;
1430
 
        }
1431
 
      }
1432
 
      keyinfo->usable_key_parts= usable_parts; // Filesort
1433
 
 
1434
 
      set_if_bigger(max_key_length,keyinfo->key_length+
1435
 
                    keyinfo->key_parts);
1436
 
      total_key_length+= keyinfo->key_length;
1437
 
 
1438
 
      if (keyinfo->flags & HA_NOSAME)
1439
 
      {
1440
 
        set_if_bigger(max_unique_length,keyinfo->key_length);
1441
 
      }
1442
 
    }
1443
 
    if (local_primary_key < MAX_KEY &&
1444
 
        (keys_in_use.test(local_primary_key)))
1445
 
    {
1446
 
      primary_key= local_primary_key;
1447
 
      /*
1448
 
        If we are using an integer as the primary key then allow the user to
1449
 
        refer to it as '_rowid'
1450
 
      */
1451
 
      if (key_info[local_primary_key].key_parts == 1)
1452
 
      {
1453
 
        Field *local_field= key_info[local_primary_key].key_part[0].field;
1454
 
        if (local_field && local_field->result_type() == INT_RESULT)
1455
 
        {
1456
 
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
1457
 
          rowid_field_offset= (key_info[local_primary_key].key_part[0].
1458
 
                                      fieldnr);
1459
 
        }
1460
 
      }
1461
 
    }
1462
 
  }
1463
 
 
1464
 
  if (found_next_number_field)
1465
 
  {
1466
 
    Field *reg_field= *found_next_number_field;
1467
 
    if ((int) (next_number_index= (uint32_t)
1468
 
               find_ref_key(key_info, keys,
1469
 
                            getDefaultValues(), reg_field,
1470
 
                            &next_number_key_offset,
1471
 
                            &next_number_keypart)) < 0)
1472
 
    {
1473
 
      /* Wrong field definition */
1474
 
      local_error= ER_NOT_FORM_FILE;
1475
 
 
1476
 
      return true;
1477
 
    }
1478
 
    else
1479
 
    {
1480
 
      reg_field->flags |= AUTO_INCREMENT_FLAG;
1481
 
    }
1482
 
  }
1483
 
 
1484
 
  if (blob_fields)
1485
 
  {
1486
 
    /* Store offsets to blob fields to find them fast */
1487
 
    blob_field.resize(blob_fields);
1488
 
    uint32_t *save= &blob_field[0];
1489
 
    uint32_t k= 0;
1490
 
    for (Fields::iterator iter= _fields.begin(); iter != _fields.end()-1; iter++, k++)
1491
 
    {
1492
 
      if ((*iter)->flags & BLOB_FLAG)
1493
 
        (*save++)= k;
1494
 
    }
1495
 
  }
1496
 
 
1497
 
  all_set.clear();
1498
 
  all_set.resize(_field_size);
1499
 
  all_set.set();
1500
 
 
1501
 
  return local_error != EE_OK;
1502
 
}
 
106
 
 
107
void TableShare::release(TableShare *share)
 
108
{
 
109
  bool to_be_deleted= false;
 
110
  safe_mutex_assert_owner(&LOCK_open);
 
111
 
 
112
  pthread_mutex_lock(&share->mutex);
 
113
  if (!--share->ref_count)
 
114
    to_be_deleted= true;
 
115
 
 
116
  if (to_be_deleted)
 
117
  {
 
118
    hash_delete(&table_def_cache, (unsigned char*) share);
 
119
    return;
 
120
  }
 
121
  pthread_mutex_unlock(&share->mutex);
 
122
}
 
123
 
 
124
void TableShare::release(const char *key, uint32_t key_length)
 
125
{
 
126
  TableShare *share;
 
127
 
 
128
  if ((share= (TableShare*) hash_search(&table_def_cache,(unsigned char*) key,
 
129
                                        key_length)))
 
130
  {
 
131
    share->version= 0;                          // Mark for delete
 
132
    if (share->ref_count == 0)
 
133
    {
 
134
      pthread_mutex_lock(&share->mutex);
 
135
      hash_delete(&table_def_cache, (unsigned char*) share);
 
136
    }
 
137
  }
 
138
}
 
139
 
 
140
 
1503
141
 
1504
142
/*
1505
 
  Read table definition from a binary / text based .frm cursor
1506
 
 
1507
 
  SYNOPSIS
1508
 
  open_table_def()
1509
 
  session               Thread Cursor
1510
 
  share         Fill this with table definition
 
143
  Get TableShare for a table.
 
144
 
 
145
  get_table_share()
 
146
  session                       Thread handle
 
147
  table_list            Table that should be opened
 
148
  key                   Table cache key
 
149
  key_length            Length of key
 
150
  error                 out: Error code from open_table_def()
 
151
 
 
152
  IMPLEMENTATION
 
153
  Get a table definition from the table definition cache.
 
154
  If it doesn't exist, create a new from the table definition file.
1511
155
 
1512
156
  NOTES
1513
 
  This function is called when the table definition is not cached in
1514
 
  definition::Cache::singleton().getCache()
1515
 
  The data is returned in 'share', which is alloced by
1516
 
  alloc_table_share().. The code assumes that share is initialized.
 
157
  We must have wrlock on LOCK_open when we come here
 
158
  (To be changed later)
1517
159
 
1518
 
  RETURN VALUES
1519
 
  0     ok
1520
 
  1     Error (see open_table_error)
1521
 
  2    Error (see open_table_error)
1522
 
  3    Wrong data in .frm cursor
1523
 
  4    Error (see open_table_error)
1524
 
  5    Error (see open_table_error: charset unavailable)
1525
 
  6    Unknown .frm version
 
160
  RETURN
 
161
  0  Error
 
162
#  Share for table
1526
163
*/
1527
164
 
1528
 
int TableShare::open_table_def(Session& session, const identifier::Table &identifier)
 
165
TableShare *TableShare::getShare(Session *session, 
 
166
                                 TableList *table_list, char *key,
 
167
                                 uint32_t key_length, uint32_t, int *error)
1529
168
{
1530
 
  drizzled::error_t local_error= EE_OK;
1531
 
 
1532
 
  message::table::shared_ptr table= plugin::StorageEngine::getTableMessage(session, identifier, local_error);
1533
 
 
1534
 
  if (table and table->IsInitialized())
1535
 
  {
1536
 
    if (parse_table_proto(session, *table))
1537
 
    {
1538
 
      local_error= ER_CORRUPT_TABLE_DEFINITION_UNKNOWN;
1539
 
      my_error(ER_CORRUPT_TABLE_DEFINITION_UNKNOWN, identifier);
1540
 
    }
1541
 
    else
1542
 
    {
1543
 
      setTableCategory(TABLE_CATEGORY_USER);
1544
 
      local_error= EE_OK;
1545
 
    }
1546
 
  }
1547
 
  else if (table and not table->IsInitialized())
1548
 
  {
1549
 
    local_error= ER_CORRUPT_TABLE_DEFINITION_UNKNOWN;
1550
 
    my_error(ER_CORRUPT_TABLE_DEFINITION_UNKNOWN, identifier);
1551
 
  }
1552
 
  else
1553
 
  {
1554
 
    local_error= ER_TABLE_UNKNOWN;
1555
 
    my_error(ER_TABLE_UNKNOWN, identifier);
1556
 
  }
1557
 
 
1558
 
  return static_cast<int>(local_error);
 
169
  TableShare *share;
 
170
 
 
171
  *error= 0;
 
172
 
 
173
  /* Read table definition from cache */
 
174
  if ((share= (TableShare*) hash_search(&table_def_cache,(unsigned char*) key,
 
175
                                        key_length)))
 
176
    goto found;
 
177
 
 
178
  if (!(share= alloc_table_share(table_list, key, key_length)))
 
179
  {
 
180
    return NULL;
 
181
  }
 
182
 
 
183
  /*
 
184
    Lock mutex to be able to read table definition from file without
 
185
    conflicts
 
186
  */
 
187
  (void) pthread_mutex_lock(&share->mutex);
 
188
 
 
189
  if (my_hash_insert(&table_def_cache, (unsigned char*) share))
 
190
  {
 
191
    share->free_table_share();
 
192
    return NULL;                                // return error
 
193
  }
 
194
  if (open_table_def(session, share))
 
195
  {
 
196
    *error= share->error;
 
197
    (void) hash_delete(&table_def_cache, (unsigned char*) share);
 
198
    return NULL;
 
199
  }
 
200
  share->ref_count++;                           // Mark in use
 
201
  (void) pthread_mutex_unlock(&share->mutex);
 
202
  return(share);
 
203
 
 
204
found:
 
205
  /*
 
206
    We found an existing table definition. Return it if we didn't get
 
207
    an error when reading the table definition from file.
 
208
  */
 
209
 
 
210
  /* We must do a lock to ensure that the structure is initialized */
 
211
  (void) pthread_mutex_lock(&share->mutex);
 
212
  if (share->error)
 
213
  {
 
214
    /* Table definition contained an error */
 
215
    share->open_table_error(share->error, share->open_errno, share->errarg);
 
216
    (void) pthread_mutex_unlock(&share->mutex);
 
217
 
 
218
    return NULL;
 
219
  }
 
220
 
 
221
  share->ref_count++;
 
222
  (void) pthread_mutex_unlock(&share->mutex);
 
223
 
 
224
  return share;
1559
225
}
1560
226
 
1561
227
 
1562
228
/*
1563
 
  Open a table based on a TableShare
 
229
  Check if table definition exits in cache
1564
230
 
1565
231
  SYNOPSIS
1566
 
  open_table_from_share()
1567
 
  session                       Thread Cursor
1568
 
  share         Table definition
1569
 
  alias         Alias for table
1570
 
  db_stat               open flags (for example HA_OPEN_KEYFILE|
1571
 
  HA_OPEN_RNDFILE..) can be 0 (example in
1572
 
  ha_example_table)
1573
 
  ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1574
 
  outparam              result table
 
232
  get_cached_table_share()
 
233
  db                    Database name
 
234
  table_name            Table name
1575
235
 
1576
 
  RETURN VALUES
1577
 
  0     ok
1578
 
  1     Error (see open_table_error)
1579
 
  2    Error (see open_table_error)
1580
 
  3    Wrong data in .frm cursor
1581
 
  4    Error (see open_table_error)
1582
 
  5    Error (see open_table_error: charset unavailable)
1583
 
  7    Table definition has changed in engine
 
236
  RETURN
 
237
  0  Not cached
 
238
#  TableShare for table
1584
239
*/
1585
 
int TableShare::open_table_from_share(Session *session,
1586
 
                                      const identifier::Table &identifier,
1587
 
                                      const char *alias,
1588
 
                                      uint32_t db_stat, uint32_t ha_open_flags,
1589
 
                                      Table &outparam)
1590
 
{
1591
 
  bool error_reported= false;
1592
 
  int ret= open_table_from_share_inner(session, alias, db_stat, outparam);
1593
 
 
1594
 
  if (not ret)
1595
 
    ret= open_table_cursor_inner(identifier, db_stat, ha_open_flags, outparam, error_reported);
1596
 
 
1597
 
  if (not ret)
1598
 
    return ret;
1599
 
 
1600
 
  if (not error_reported)
1601
 
    open_table_error(ret, errno, 0);
1602
 
 
1603
 
  boost::checked_delete(outparam.cursor);
1604
 
  outparam.cursor= 0;                           // For easier error checking
1605
 
  outparam.db_stat= 0;
1606
 
  outparam.getMemRoot()->free_root(MYF(0));       // Safe to call on zeroed root
1607
 
  outparam.clearAlias();
1608
 
 
1609
 
  return ret;
1610
 
}
1611
 
 
1612
 
int TableShare::open_table_from_share_inner(Session *session,
1613
 
                                            const char *alias,
1614
 
                                            uint32_t db_stat,
1615
 
                                            Table &outparam)
1616
 
{
1617
 
  int local_error;
1618
 
  uint32_t records;
1619
 
  unsigned char *record= NULL;
1620
 
  Field **field_ptr;
1621
 
 
1622
 
  local_error= 1;
1623
 
  outparam.resetTable(session, this, db_stat);
1624
 
 
1625
 
  outparam.setAlias(alias);
1626
 
 
1627
 
  /* Allocate Cursor */
1628
 
  if (not (outparam.cursor= db_type()->getCursor(outparam)))
1629
 
    return local_error;
1630
 
 
1631
 
  local_error= 4;
1632
 
  records= 0;
1633
 
  if ((db_stat & HA_OPEN_KEYFILE))
1634
 
    records=1;
1635
 
 
1636
 
  records++;
1637
 
 
1638
 
  if (!(record= (unsigned char*) outparam.alloc_root(rec_buff_length * records)))
1639
 
    return local_error;
1640
 
 
1641
 
  if (records == 0)
1642
 
  {
1643
 
    /* We are probably in hard repair, and the buffers should not be used */
1644
 
    outparam.record[0]= outparam.record[1]= getDefaultValues();
1645
 
  }
1646
 
  else
1647
 
  {
1648
 
    outparam.record[0]= record;
1649
 
    if (records > 1)
1650
 
      outparam.record[1]= record+ rec_buff_length;
1651
 
    else
1652
 
      outparam.record[1]= outparam.getInsertRecord();   // Safety
1653
 
  }
1654
 
 
1655
 
#ifdef HAVE_VALGRIND
1656
 
  /*
1657
 
    We need this because when we read var-length rows, we are not updating
1658
 
    bytes after end of varchar
1659
 
  */
1660
 
  if (records > 1)
1661
 
  {
1662
 
    memcpy(outparam.getInsertRecord(), getDefaultValues(), rec_buff_length);
1663
 
    memcpy(outparam.getUpdateRecord(), getDefaultValues(), null_bytes);
1664
 
    if (records > 2)
1665
 
      memcpy(outparam.getUpdateRecord(), getDefaultValues(), rec_buff_length);
1666
 
  }
1667
 
#endif
1668
 
  if (records > 1)
1669
 
  {
1670
 
    memcpy(outparam.getUpdateRecord(), getDefaultValues(), null_bytes);
1671
 
  }
1672
 
 
1673
 
  if (!(field_ptr = (Field **) outparam.alloc_root( (uint32_t) ((_field_size+1)* sizeof(Field*)))))
1674
 
  {
1675
 
    return local_error;
1676
 
  }
1677
 
 
1678
 
  outparam.setFields(field_ptr);
1679
 
 
1680
 
  record= (unsigned char*) outparam.getInsertRecord()-1;        /* Fieldstart = 1 */
1681
 
 
1682
 
  outparam.null_flags= (unsigned char*) record+1;
1683
 
 
1684
 
  /* Setup copy of fields from share, but use the right alias and record */
1685
 
  for (uint32_t i= 0 ; i < _field_size; i++, field_ptr++)
1686
 
  {
1687
 
    if (!((*field_ptr)= _fields[i]->clone(outparam.getMemRoot(), &outparam)))
1688
 
      return local_error;
1689
 
  }
1690
 
  (*field_ptr)= 0;                              // End marker
1691
 
 
1692
 
  if (found_next_number_field)
1693
 
    outparam.found_next_number_field=
1694
 
      outparam.getField(positionFields(found_next_number_field));
1695
 
  if (timestamp_field)
1696
 
    outparam.timestamp_field= (field::Epoch*) outparam.getField(timestamp_field->position());
1697
 
 
1698
 
  /* Fix key->name and key_part->field */
1699
 
  if (key_parts)
1700
 
  {
1701
 
    KeyInfo     *local_key_info, *key_info_end;
1702
 
    KeyPartInfo *key_part;
1703
 
    uint32_t n_length;
1704
 
    n_length= keys*sizeof(KeyInfo) + key_parts*sizeof(KeyPartInfo);
1705
 
    if (!(local_key_info= (KeyInfo*) outparam.alloc_root(n_length)))
1706
 
      return local_error;
1707
 
    outparam.key_info= local_key_info;
1708
 
    key_part= (reinterpret_cast<KeyPartInfo*> (local_key_info+keys));
1709
 
 
1710
 
    memcpy(local_key_info, key_info, sizeof(*local_key_info)*keys);
1711
 
    memcpy(key_part, key_info[0].key_part, (sizeof(*key_part) *
1712
 
                                            key_parts));
1713
 
 
1714
 
    for (key_info_end= local_key_info + keys ;
1715
 
         local_key_info < key_info_end ;
1716
 
         local_key_info++)
1717
 
    {
1718
 
      KeyPartInfo *key_part_end;
1719
 
 
1720
 
      local_key_info->table= &outparam;
1721
 
      local_key_info->key_part= key_part;
1722
 
 
1723
 
      for (key_part_end= key_part+ local_key_info->key_parts ;
1724
 
           key_part < key_part_end ;
1725
 
           key_part++)
1726
 
      {
1727
 
        Field *local_field= key_part->field= outparam.getField(key_part->fieldnr-1);
1728
 
 
1729
 
        if (local_field->key_length() != key_part->length &&
1730
 
            !(local_field->flags & BLOB_FLAG))
1731
 
        {
1732
 
          /*
1733
 
            We are using only a prefix of the column as a key:
1734
 
            Create a new field for the key part that matches the index
1735
 
          */
1736
 
          local_field= key_part->field= local_field->new_field(outparam.getMemRoot(), &outparam, 0);
1737
 
          local_field->field_length= key_part->length;
1738
 
        }
1739
 
      }
1740
 
    }
1741
 
  }
1742
 
 
1743
 
  /* Allocate bitmaps */
1744
 
 
1745
 
  outparam.def_read_set.resize(_field_size);
1746
 
  outparam.def_write_set.resize(_field_size);
1747
 
  outparam.tmp_set.resize(_field_size);
1748
 
  outparam.default_column_bitmaps();
1749
 
 
1750
 
  return 0;
1751
 
}
1752
 
 
1753
 
int TableShare::open_table_cursor_inner(const identifier::Table &identifier,
1754
 
                                        uint32_t db_stat, uint32_t ha_open_flags,
1755
 
                                        Table &outparam,
1756
 
                                        bool &error_reported)
1757
 
{
1758
 
  /* The table struct is now initialized;  Open the table */
1759
 
  int local_error= 2;
1760
 
  if (db_stat)
1761
 
  {
1762
 
    assert(!(db_stat & HA_WAIT_IF_LOCKED));
1763
 
    int ha_err;
1764
 
 
1765
 
    if ((ha_err= (outparam.cursor->ha_open(identifier,
1766
 
                                           (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1767
 
                                           (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1768
 
    {
1769
 
      switch (ha_err)
1770
 
      {
1771
 
      case HA_ERR_NO_SUCH_TABLE:
1772
 
        /*
1773
 
          The table did not exists in storage engine, use same error message
1774
 
          as if the .frm cursor didn't exist
1775
 
        */
1776
 
        local_error= 1;
1777
 
        errno= ENOENT;
1778
 
        break;
1779
 
      case EMFILE:
1780
 
        /*
1781
 
          Too many files opened, use same error message as if the .frm
1782
 
          cursor can't open
1783
 
        */
1784
 
        local_error= 1;
1785
 
        errno= EMFILE;
1786
 
        break;
1787
 
      default:
1788
 
        outparam.print_error(ha_err, MYF(0));
1789
 
        error_reported= true;
1790
 
        if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1791
 
          local_error= 7;
1792
 
        break;
1793
 
      }
1794
 
      return local_error;
1795
 
    }
1796
 
  }
1797
 
 
1798
 
  return 0;
1799
 
}
1800
 
 
1801
 
/* error message when opening a form cursor */
1802
 
void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
1803
 
{
1804
 
  char buff[FN_REFLEN];
1805
 
  myf errortype= ME_ERROR+ME_WAITTANG;
1806
 
 
1807
 
  switch (pass_error) {
1808
 
  case 7:
1809
 
  case 1:
1810
 
    if (db_errno == ENOENT)
1811
 
    {
1812
 
      identifier::Table identifier(db.str, table_name.str);
1813
 
      my_error(ER_TABLE_UNKNOWN, identifier);
1814
 
    }
1815
 
    else
1816
 
    {
1817
 
      snprintf(buff, sizeof(buff), "%s",normalized_path.str);
1818
 
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1819
 
               errortype, buff, db_errno);
1820
 
    }
1821
 
    break;
1822
 
  case 2:
1823
 
    {
1824
 
      drizzled::error_t err_no;
1825
 
 
1826
 
      err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1827
 
        ER_FILE_USED : ER_CANT_OPEN_FILE;
1828
 
 
1829
 
      my_error(err_no, errortype, normalized_path.str, db_errno);
1830
 
      break;
1831
 
    }
1832
 
  case 5:
1833
 
    {
1834
 
      const char *csname= get_charset_name((uint32_t) pass_errarg);
1835
 
      char tmp[10];
1836
 
      if (!csname || csname[0] =='?')
1837
 
      {
1838
 
        snprintf(tmp, sizeof(tmp), "#%d", pass_errarg);
1839
 
        csname= tmp;
1840
 
      }
1841
 
      my_printf_error(ER_UNKNOWN_COLLATION,
1842
 
                      _("Unknown collation '%s' in table '%-.64s' definition"),
1843
 
                      MYF(0), csname, table_name.str);
1844
 
      break;
1845
 
    }
1846
 
  case 6:
1847
 
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
1848
 
    my_printf_error(ER_NOT_FORM_FILE,
1849
 
                    _("Table '%-.64s' was created with a different version "
1850
 
                      "of Drizzle and cannot be read"),
1851
 
                    MYF(0), buff);
1852
 
    break;
1853
 
  case 8:
1854
 
    break;
1855
 
  default:                              /* Better wrong error than none */
1856
 
  case 4:
1857
 
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
1858
 
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1859
 
    break;
1860
 
  }
1861
 
  return;
1862
 
} /* open_table_error */
1863
 
 
1864
 
Field *TableShare::make_field(const message::Table::Field &pfield,
1865
 
                              unsigned char *ptr,
1866
 
                              uint32_t field_length,
1867
 
                              bool is_nullable,
1868
 
                              unsigned char *null_pos,
1869
 
                              unsigned char null_bit,
1870
 
                              uint8_t decimals,
1871
 
                              enum_field_types field_type,
1872
 
                              const CHARSET_INFO * field_charset,
1873
 
                              Field::utype unireg_check,
1874
 
                              TYPELIB *interval,
1875
 
                              const char *field_name)
1876
 
{
1877
 
  return make_field(pfield,
1878
 
                    ptr,
1879
 
                    field_length,
1880
 
                    is_nullable,
1881
 
                    null_pos,
1882
 
                    null_bit,
1883
 
                    decimals,
1884
 
                    field_type,
1885
 
                    field_charset,
1886
 
                    unireg_check,
1887
 
                    interval,
1888
 
                    field_name,
1889
 
                    pfield.constraints().is_unsigned());
1890
 
}
1891
 
 
1892
 
Field *TableShare::make_field(const message::Table::Field &,
1893
 
                              unsigned char *ptr,
1894
 
                              uint32_t field_length,
1895
 
                              bool is_nullable,
1896
 
                              unsigned char *null_pos,
1897
 
                              unsigned char null_bit,
1898
 
                              uint8_t decimals,
1899
 
                              enum_field_types field_type,
1900
 
                              const CHARSET_INFO * field_charset,
1901
 
                              Field::utype unireg_check,
1902
 
                              TYPELIB *interval,
1903
 
                              const char *field_name, 
1904
 
                              bool is_unsigned)
1905
 
{
1906
 
  if (! is_nullable)
1907
 
  {
1908
 
    null_pos=0;
1909
 
    null_bit=0;
1910
 
  }
1911
 
  else
1912
 
  {
1913
 
    null_bit= ((unsigned char) 1) << null_bit;
1914
 
  }
1915
 
 
1916
 
  switch (field_type) 
1917
 
  {
1918
 
  case DRIZZLE_TYPE_DATE:
1919
 
  case DRIZZLE_TYPE_DATETIME:
1920
 
  case DRIZZLE_TYPE_UUID:
1921
 
    field_charset= &my_charset_bin;
1922
 
  default: break;
1923
 
  }
1924
 
 
1925
 
  switch (field_type)
1926
 
  {
1927
 
  case DRIZZLE_TYPE_ENUM:
1928
 
    return new (&mem_root) Field_enum(ptr,
1929
 
                                      field_length,
1930
 
                                      null_pos,
1931
 
                                      null_bit,
1932
 
                                      field_name,
1933
 
                                      interval,
1934
 
                                      field_charset);
1935
 
  case DRIZZLE_TYPE_VARCHAR:
1936
 
    setVariableWidth();
1937
 
    return new (&mem_root) Field_varstring(ptr,field_length,
1938
 
                                      ha_varchar_packlength(field_length),
1939
 
                                      null_pos,null_bit,
1940
 
                                      field_name,
1941
 
                                      field_charset);
1942
 
  case DRIZZLE_TYPE_BLOB:
1943
 
    return new (&mem_root) Field_blob(ptr,
1944
 
                                      null_pos,
1945
 
                                      null_bit,
1946
 
                                      field_name,
1947
 
                                      this,
1948
 
                                      field_charset);
1949
 
  case DRIZZLE_TYPE_DECIMAL:
1950
 
    return new (&mem_root) Field_decimal(ptr,
1951
 
                                         field_length,
1952
 
                                         null_pos,
1953
 
                                         null_bit,
1954
 
                                         unireg_check,
1955
 
                                         field_name,
1956
 
                                         decimals);
1957
 
  case DRIZZLE_TYPE_DOUBLE:
1958
 
    return new (&mem_root) Field_double(ptr,
1959
 
                                   field_length,
1960
 
                                   null_pos,
1961
 
                                   null_bit,
1962
 
                                   unireg_check,
1963
 
                                   field_name,
1964
 
                                   decimals,
1965
 
                                   false,
1966
 
                                   false /* is_unsigned */);
1967
 
  case DRIZZLE_TYPE_UUID:
1968
 
    return new (&mem_root) field::Uuid(ptr,
1969
 
                                       field_length,
1970
 
                                       null_pos,
1971
 
                                       null_bit,
1972
 
                                       field_name);
1973
 
  case DRIZZLE_TYPE_BOOLEAN:
1974
 
    return new (&mem_root) field::Boolean(ptr,
1975
 
                                          field_length,
1976
 
                                          null_pos,
1977
 
                                          null_bit,
1978
 
                                          field_name,
1979
 
                                          is_unsigned);
1980
 
  case DRIZZLE_TYPE_LONG:
1981
 
    return new (&mem_root) field::Int32(ptr,
1982
 
                                        field_length,
1983
 
                                        null_pos,
1984
 
                                        null_bit,
1985
 
                                        unireg_check,
1986
 
                                        field_name);
1987
 
  case DRIZZLE_TYPE_LONGLONG:
1988
 
    {
1989
 
      if (is_unsigned)
1990
 
      {
1991
 
        return new (&mem_root) field::Size(ptr,
1992
 
                                           field_length,
1993
 
                                           null_pos,
1994
 
                                           null_bit,
1995
 
                                           unireg_check,
1996
 
                                           field_name);
1997
 
      }
1998
 
 
1999
 
      return new (&mem_root) field::Int64(ptr,
2000
 
                                          field_length,
2001
 
                                          null_pos,
2002
 
                                          null_bit,
2003
 
                                          unireg_check,
2004
 
                                          field_name);
2005
 
    }
2006
 
  case DRIZZLE_TYPE_MICROTIME:
2007
 
    return new (&mem_root) field::Microtime(ptr,
2008
 
                                            null_pos,
2009
 
                                            null_bit,
2010
 
                                            unireg_check,
2011
 
                                            field_name,
2012
 
                                            this);
2013
 
  case DRIZZLE_TYPE_TIMESTAMP:
2014
 
    return new (&mem_root) field::Epoch(ptr,
2015
 
                                        null_pos,
2016
 
                                        null_bit,
2017
 
                                        unireg_check,
2018
 
                                        field_name,
2019
 
                                        this);
2020
 
  case DRIZZLE_TYPE_TIME:
2021
 
    return new (&mem_root) field::Time(ptr,
2022
 
                                       field_length,
2023
 
                                       null_pos,
2024
 
                                       null_bit,
2025
 
                                       field_name,
2026
 
                                       field_charset);
2027
 
  case DRIZZLE_TYPE_DATE:
2028
 
    return new (&mem_root) Field_date(ptr,
2029
 
                                 null_pos,
2030
 
                                 null_bit,
2031
 
                                 field_name,
2032
 
                                 field_charset);
2033
 
  case DRIZZLE_TYPE_DATETIME:
2034
 
    return new (&mem_root) Field_datetime(ptr,
2035
 
                                     null_pos,
2036
 
                                     null_bit,
2037
 
                                     field_name,
2038
 
                                     field_charset);
2039
 
  case DRIZZLE_TYPE_NULL:
2040
 
    return new (&mem_root) Field_null(ptr,
2041
 
                                 field_length,
2042
 
                                 field_name,
2043
 
                                 field_charset);
2044
 
  }
2045
 
  assert(0);
2046
 
  abort();
2047
 
}
2048
 
 
2049
 
void TableShare::refreshVersion()
2050
 
{
2051
 
  version= refresh_version;
2052
 
}
2053
 
 
2054
 
 
2055
 
} /* namespace drizzled */
 
240
 
 
241
TableShare *TableShare::getShare(const char *db, const char *table_name)
 
242
{
 
243
  char key[NAME_LEN*2+2];
 
244
  uint32_t key_length;
 
245
  safe_mutex_assert_owner(&LOCK_open);
 
246
 
 
247
  key_length= TableShare::createKey(key, db, table_name);
 
248
 
 
249
  return (TableShare*) hash_search(&table_def_cache,(unsigned char*) key, key_length);
 
250
}