~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_share.cc

  • Committer: Stewart Smith
  • Date: 2010-07-27 00:49:32 UTC
  • mto: (1720.1.1 drizzle)
  • mto: This revision was merged to the branch mainline in revision 1721.
  • Revision ID: stewart@flamingspork.com-20100727004932-basq3vx9szmmbswm
fix storing and manipulating foreign keys in the proto around ALTER TABLE, CREATE TABLE and ALTER TABLE ADD/DROP FOREIGN KEY. We also (mostly) emulate the naming of innodb foreign keys in the upper layer.

Show diffs side-by-side

added added

removed removed

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