~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_share.cc

  • Committer: Monty Taylor
  • Date: 2010-08-21 03:34:31 UTC
  • mto: (1725.1.3 build)
  • mto: This revision was merged to the branch mainline in revision 1726.
  • Revision ID: mordred@inaugust.com-20100821033431-e0czq298av2aqx25
Rearranged how we set -fvisibility, allowing us to turn it on on a
library-by-library basis even if we specify skip-visiblity as an argument to
PANDORA_CANONICAL.

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