~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_share.cc

  • Committer: Brian Aker
  • Date: 2010-07-15 23:18:11 UTC
  • mto: This revision was merged to the branch mainline in revision 1661.
  • Revision ID: brian@gaz-20100715231811-c5erivy1nvwf6bii
Merge in move identifier work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; i/dent-tabs-mode: nil; -*-
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
4
 *  Copyright (C) 2010 Brian Aker
44
44
#include "drizzled/internal/my_pthread.h"
45
45
#include "drizzled/plugin/event_observer.h"
46
46
 
47
 
#include "drizzled/table.h"
48
 
#include "drizzled/table/shell.h"
49
 
 
50
47
#include "drizzled/session.h"
51
48
 
52
49
#include "drizzled/charset.h"
70
67
#include "drizzled/field/decimal.h"
71
68
#include "drizzled/field/real.h"
72
69
#include "drizzled/field/double.h"
73
 
#include "drizzled/field/int32.h"
74
 
#include "drizzled/field/int64.h"
 
70
#include "drizzled/field/long.h"
 
71
#include "drizzled/field/int64_t.h"
75
72
#include "drizzled/field/num.h"
76
73
#include "drizzled/field/timestamp.h"
77
74
#include "drizzled/field/datetime.h"
78
75
#include "drizzled/field/varstring.h"
79
 
#include "drizzled/field/uuid.h"
80
 
 
81
 
#include "drizzled/definition/cache.h"
82
76
 
83
77
using namespace std;
84
78
 
86
80
{
87
81
 
88
82
extern size_t table_def_size;
 
83
static TableDefinitionCache table_def_cache;
 
84
static pthread_mutex_t LOCK_table_share;
 
85
bool table_def_inited= false;
89
86
 
90
87
/*****************************************************************************
91
88
  Functions to handle table definition cach (TableShare)
92
89
 *****************************************************************************/
93
90
 
 
91
 
 
92
void TableShare::cacheStart(void)
 
93
{
 
94
  pthread_mutex_init(&LOCK_table_share, MY_MUTEX_INIT_FAST);
 
95
  table_def_inited= true;
 
96
  /* 
 
97
   * This is going to overalloc a bit - as rehash sets the number of
 
98
   * buckets, not the number of elements. BUT, it'll allow us to not need
 
99
   * to rehash later on as the unordered_map grows.
 
100
 */
 
101
  table_def_cache.rehash(table_def_size);
 
102
}
 
103
 
 
104
 
 
105
void TableShare::cacheStop(void)
 
106
{
 
107
  if (table_def_inited)
 
108
  {
 
109
    table_def_inited= false;
 
110
    pthread_mutex_destroy(&LOCK_table_share);
 
111
  }
 
112
}
 
113
 
 
114
 
 
115
/**
 
116
 * @TODO: This should return size_t
 
117
 */
 
118
uint32_t cached_table_definitions(void)
 
119
{
 
120
  return static_cast<uint32_t>(table_def_cache.size());
 
121
}
 
122
 
 
123
 
94
124
/*
95
125
  Mark that we are not using table share anymore.
96
126
 
106
136
void TableShare::release(TableShare *share)
107
137
{
108
138
  bool to_be_deleted= false;
109
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle);
110
 
 
111
 
  share->lock();
112
 
  if (!--share->ref_count)
113
 
  {
114
 
    to_be_deleted= true;
115
 
  }
116
 
  share->unlock();
117
 
 
118
 
  if (to_be_deleted)
119
 
  {
120
 
    definition::Cache::singleton().erase(share->getCacheKey());
121
 
  }
122
 
}
123
 
 
124
 
void TableShare::release(TableShare::shared_ptr &share)
125
 
{
126
 
  bool to_be_deleted= false;
127
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle);
128
 
 
129
 
  share->lock();
130
 
  if (!--share->ref_count)
131
 
  {
132
 
    to_be_deleted= true;
133
 
  }
134
 
  share->unlock();
135
 
 
136
 
  if (to_be_deleted)
137
 
  {
138
 
    definition::Cache::singleton().erase(share->getCacheKey());
139
 
  }
140
 
}
141
 
 
142
 
void TableShare::release(const TableIdentifier &identifier)
143
 
{
144
 
  TableShare::shared_ptr share= definition::Cache::singleton().find(identifier.getKey());
145
 
  if (share)
146
 
  {
 
139
  safe_mutex_assert_owner(&LOCK_open);
 
140
 
 
141
  pthread_mutex_lock(&share->mutex);
 
142
  if (!--share->ref_count)
 
143
  {
 
144
    to_be_deleted= true;
 
145
  }
 
146
 
 
147
  if (to_be_deleted)
 
148
  {
 
149
    TableIdentifier identifier(share->getSchemaName(), share->getTableName());
 
150
    plugin::EventObserver::deregisterTableEvents(*share);
 
151
   
 
152
    TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
 
153
    if (iter != table_def_cache.end())
 
154
    {
 
155
      table_def_cache.erase(iter);
 
156
      delete share;
 
157
    }
 
158
    return;
 
159
  }
 
160
  pthread_mutex_unlock(&share->mutex);
 
161
}
 
162
 
 
163
void TableShare::release(TableIdentifier &identifier)
 
164
{
 
165
  TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
 
166
  if (iter != table_def_cache.end())
 
167
  {
 
168
    TableShare *share= (*iter).second;
147
169
    share->version= 0;                          // Mark for delete
148
170
    if (share->ref_count == 0)
149
171
    {
150
 
      definition::Cache::singleton().erase(identifier.getKey());
 
172
      pthread_mutex_lock(&share->mutex);
 
173
      plugin::EventObserver::deregisterTableEvents(*share);
 
174
      table_def_cache.erase(identifier.getKey());
 
175
      delete share;
151
176
    }
152
177
  }
153
178
}
154
179
 
155
180
 
156
 
static TableShare::shared_ptr foundTableShare(TableShare::shared_ptr share)
 
181
static TableShare *foundTableShare(TableShare *share)
157
182
{
158
183
  /*
159
184
    We found an existing table definition. Return it if we didn't get
161
186
  */
162
187
 
163
188
  /* We must do a lock to ensure that the structure is initialized */
 
189
  (void) pthread_mutex_lock(&share->mutex);
164
190
  if (share->error)
165
191
  {
166
192
    /* Table definition contained an error */
167
193
    share->open_table_error(share->error, share->open_errno, share->errarg);
 
194
    (void) pthread_mutex_unlock(&share->mutex);
168
195
 
169
 
    return TableShare::shared_ptr();
 
196
    return NULL;
170
197
  }
171
198
 
172
199
  share->incrementTableCount();
 
200
  (void) pthread_mutex_unlock(&share->mutex);
173
201
 
174
202
  return share;
175
203
}
189
217
  If it doesn't exist, create a new from the table definition file.
190
218
 
191
219
  NOTES
192
 
  We must have wrlock on table::Cache::singleton().mutex() when we come here
 
220
  We must have wrlock on LOCK_open when we come here
193
221
  (To be changed later)
194
222
 
195
223
  RETURN
197
225
#  Share for table
198
226
*/
199
227
 
200
 
TableShare::shared_ptr TableShare::getShareCreate(Session *session, 
201
 
                                                  const TableIdentifier &identifier,
202
 
                                                  int &in_error)
 
228
TableShare *TableShare::getShareCreate(Session *session, 
 
229
                                       TableIdentifier &identifier,
 
230
                                       int *error)
203
231
{
204
 
  TableShare::shared_ptr share;
 
232
  TableShare *share= NULL;
205
233
 
206
 
  in_error= 0;
 
234
  *error= 0;
207
235
 
208
236
  /* Read table definition from cache */
209
 
  if ((share= definition::Cache::singleton().find(identifier.getKey())))
 
237
  TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
 
238
  if (iter != table_def_cache.end())
 
239
  {
 
240
    share= (*iter).second;
210
241
    return foundTableShare(share);
211
 
 
212
 
  share.reset(new TableShare(message::Table::STANDARD, identifier));
213
 
  
 
242
  }
 
243
 
 
244
  if (not (share= new TableShare(message::Table::STANDARD, identifier)))
 
245
  {
 
246
    return NULL;
 
247
  }
 
248
 
 
249
  /*
 
250
    Lock mutex to be able to read table definition from file without
 
251
    conflicts
 
252
  */
 
253
  (void) pthread_mutex_lock(&share->mutex);
 
254
 
 
255
  /**
 
256
   * @TODO: we need to eject something if we exceed table_def_size
 
257
 */
 
258
  pair<TableDefinitionCache::iterator, bool> ret=
 
259
    table_def_cache.insert(make_pair(identifier.getKey(), share));
 
260
  if (ret.second == false)
 
261
  {
 
262
    delete share;
 
263
 
 
264
    return NULL;
 
265
  }
 
266
 
214
267
  if (share->open_table_def(*session, identifier))
215
268
  {
216
 
    in_error= share->error;
 
269
    *error= share->error;
 
270
    table_def_cache.erase(identifier.getKey());
 
271
    delete share;
217
272
 
218
 
    return TableShare::shared_ptr();
 
273
    return NULL;
219
274
  }
220
275
  share->ref_count++;                           // Mark in use
221
276
  
222
277
  plugin::EventObserver::registerTableEvents(*share);
223
 
 
224
 
  bool ret= definition::Cache::singleton().insert(identifier.getKey(), share);
225
 
 
226
 
  if (not ret)
227
 
    return TableShare::shared_ptr();
 
278
  
 
279
  (void) pthread_mutex_unlock(&share->mutex);
228
280
 
229
281
  return share;
230
282
}
231
283
 
 
284
 
 
285
/*
 
286
  Check if table definition exits in cache
 
287
 
 
288
  SYNOPSIS
 
289
  get_cached_table_share()
 
290
  db                    Database name
 
291
  table_name            Table name
 
292
 
 
293
  RETURN
 
294
  0  Not cached
 
295
#  TableShare for table
 
296
*/
 
297
TableShare *TableShare::getShare(TableIdentifier &identifier)
 
298
{
 
299
  safe_mutex_assert_owner(&LOCK_open);
 
300
 
 
301
  TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
 
302
  if (iter != table_def_cache.end())
 
303
  {
 
304
    return (*iter).second;
 
305
  }
 
306
  else
 
307
  {
 
308
    return NULL;
 
309
  }
 
310
}
 
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
 
232
320
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
233
321
{
234
322
  enum_field_types field_type;
265
353
  case message::Table::Field::BLOB:
266
354
    field_type= DRIZZLE_TYPE_BLOB;
267
355
    break;
268
 
  case message::Table::Field::UUID:
269
 
    field_type= DRIZZLE_TYPE_UUID;
270
 
    break;
271
356
  default:
272
 
    assert(0);
273
 
    abort(); // Programming error
 
357
    field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
 
358
    assert(1);
274
359
  }
275
360
 
276
361
  return field_type;
304
389
                                 default_value->length());
305
390
    break;
306
391
  case DRIZZLE_TYPE_NULL:
307
 
    assert(0);
308
 
    abort();
 
392
    assert(false);
309
393
  case DRIZZLE_TYPE_TIMESTAMP:
310
394
  case DRIZZLE_TYPE_DATETIME:
311
395
  case DRIZZLE_TYPE_DATE:
 
396
    if (default_value->compare("NOW()") == 0)
 
397
      break;
312
398
  case DRIZZLE_TYPE_ENUM:
313
 
  case DRIZZLE_TYPE_UUID:
314
399
    default_item= new Item_string(default_value->c_str(),
315
400
                                  default_value->length(),
316
401
                                  system_charset_info);
361
446
      size_t num_parts= index.index_part_size();
362
447
      for (size_t y= 0; y < num_parts; ++y)
363
448
      {
364
 
        if (index.index_part(y).fieldnr() == in_field->position())
 
449
        if (index.index_part(y).fieldnr() == in_field->field_index)
365
450
          return true;
366
451
      }
367
452
    }
369
454
  return false;
370
455
}
371
456
 
372
 
TableShare::TableShare(const TableIdentifier::Type type_arg) :
 
457
const TableDefinitionCache &TableShare::getCache()
 
458
{
 
459
  return table_def_cache;
 
460
}
 
461
 
 
462
TableShare::TableShare(TableIdentifier::Type type_arg) :
373
463
  table_category(TABLE_UNKNOWN_CATEGORY),
 
464
  open_count(0),
374
465
  found_next_number_field(NULL),
375
466
  timestamp_field(NULL),
376
467
  key_info(NULL),
377
 
  mem_root(TABLE_ALLOC_BLOCK_SIZE),
378
 
  all_set(),
 
468
  blob_field(NULL),
379
469
  block_size(0),
380
470
  version(0),
381
471
  timestamp_offset(0),
382
472
  reclength(0),
383
473
  stored_rec_length(0),
 
474
  row_type(ROW_TYPE_DEFAULT),
384
475
  max_rows(0),
385
476
  table_proto(NULL),
386
477
  storage_engine(NULL),
398
489
  uniques(0),
399
490
  null_fields(0),
400
491
  blob_fields(0),
401
 
  has_variable_width(false),
 
492
  timestamp_field_offset(0),
 
493
  varchar_fields(0),
402
494
  db_create_options(0),
403
495
  db_options_in_use(0),
404
496
  db_record_offset(0),
410
502
  error(0),
411
503
  open_errno(0),
412
504
  errarg(0),
 
505
  column_bitmap_size(0),
413
506
  blob_ptr_size(0),
414
507
  db_low_byte_first(false),
 
508
  name_lock(false),
 
509
  replace_with_name_lock(false),
 
510
  waiting_on_cond(false),
415
511
  keys_in_use(0),
416
512
  keys_for_keyread(0),
417
 
  event_observers(NULL)
 
513
  event_observers(NULL),
 
514
  newed(true)
418
515
{
 
516
  memset(&name_hash, 0, sizeof(HASH));
419
517
 
420
518
  table_charset= 0;
421
519
  memset(&db, 0, sizeof(LEX_STRING));
425
523
 
426
524
  if (type_arg == message::Table::INTERNAL)
427
525
  {
428
 
    TableIdentifier::build_tmptable_filename(private_key_for_cache.vectorPtr());
429
 
    init(private_key_for_cache.vector(), private_key_for_cache.vector());
 
526
    TableIdentifier::build_tmptable_filename(private_key_for_cache);
 
527
    init(&private_key_for_cache[0], &private_key_for_cache[0]);
430
528
  }
431
529
  else
432
530
  {
434
532
  }
435
533
}
436
534
 
437
 
TableShare::TableShare(const TableIdentifier &identifier, const TableIdentifier::Key &key) :// Used by placeholder
 
535
TableShare::TableShare(TableIdentifier &identifier, const TableIdentifier::Key &key) :// Used by placeholder
438
536
  table_category(TABLE_UNKNOWN_CATEGORY),
 
537
  open_count(0),
439
538
  found_next_number_field(NULL),
440
539
  timestamp_field(NULL),
441
540
  key_info(NULL),
442
 
  mem_root(TABLE_ALLOC_BLOCK_SIZE),
443
 
  all_set(),
 
541
  blob_field(NULL),
444
542
  block_size(0),
445
543
  version(0),
446
544
  timestamp_offset(0),
447
545
  reclength(0),
448
546
  stored_rec_length(0),
 
547
  row_type(ROW_TYPE_DEFAULT),
449
548
  max_rows(0),
450
549
  table_proto(NULL),
451
550
  storage_engine(NULL),
463
562
  uniques(0),
464
563
  null_fields(0),
465
564
  blob_fields(0),
466
 
  has_variable_width(false),
 
565
  timestamp_field_offset(0),
 
566
  varchar_fields(0),
467
567
  db_create_options(0),
468
568
  db_options_in_use(0),
469
569
  db_record_offset(0),
475
575
  error(0),
476
576
  open_errno(0),
477
577
  errarg(0),
 
578
  column_bitmap_size(0),
478
579
  blob_ptr_size(0),
479
580
  db_low_byte_first(false),
 
581
  name_lock(false),
 
582
  replace_with_name_lock(false),
 
583
  waiting_on_cond(false),
480
584
  keys_in_use(0),
481
585
  keys_for_keyread(0),
482
 
  event_observers(NULL)
 
586
  event_observers(NULL),
 
587
  newed(true)
483
588
{
 
589
  memset(&name_hash, 0, sizeof(HASH));
 
590
 
484
591
  assert(identifier.getKey() == key);
485
592
 
486
593
  table_charset= 0;
489
596
 
490
597
  private_key_for_cache= key;
491
598
 
 
599
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
492
600
  table_category=         TABLE_CATEGORY_TEMPORARY;
493
601
  tmp_table=              message::Table::INTERNAL;
494
602
 
495
 
  db.str= const_cast<char *>(private_key_for_cache.vector());
496
 
  db.length= strlen(private_key_for_cache.vector());
 
603
  db.str= &private_key_for_cache[0];
 
604
  db.length= strlen(&private_key_for_cache[0]);
497
605
 
498
 
  table_name.str= const_cast<char *>(private_key_for_cache.vector()) + strlen(private_key_for_cache.vector()) + 1;
 
606
  table_name.str= &private_key_for_cache[0] + strlen(&private_key_for_cache[0]) + 1;
499
607
  table_name.length= strlen(table_name.str);
500
608
  path.str= (char *)"";
501
609
  normalized_path.str= path.str;
502
610
  path.length= normalized_path.length= 0;
503
 
 
504
 
  std::string tb_name(identifier.getTableName());
505
 
  std::transform(tb_name.begin(), tb_name.end(), tb_name.begin(), ::tolower);
506
 
  assert(strcmp(tb_name.c_str(), table_name.str) == 0);
507
 
 
 
611
  assert(strcmp(identifier.getTableName().c_str(), table_name.str) == 0);
508
612
  assert(strcmp(identifier.getSchemaName().c_str(), db.str) == 0);
509
613
}
510
614
 
511
615
 
512
616
TableShare::TableShare(const TableIdentifier &identifier) : // Just used during createTable()
513
617
  table_category(TABLE_UNKNOWN_CATEGORY),
 
618
  open_count(0),
514
619
  found_next_number_field(NULL),
515
620
  timestamp_field(NULL),
516
621
  key_info(NULL),
517
 
  mem_root(TABLE_ALLOC_BLOCK_SIZE),
518
 
  all_set(),
 
622
  blob_field(NULL),
519
623
  block_size(0),
520
624
  version(0),
521
625
  timestamp_offset(0),
522
626
  reclength(0),
523
627
  stored_rec_length(0),
 
628
  row_type(ROW_TYPE_DEFAULT),
524
629
  max_rows(0),
525
630
  table_proto(NULL),
526
631
  storage_engine(NULL),
538
643
  uniques(0),
539
644
  null_fields(0),
540
645
  blob_fields(0),
541
 
  has_variable_width(false),
 
646
  timestamp_field_offset(0),
 
647
  varchar_fields(0),
542
648
  db_create_options(0),
543
649
  db_options_in_use(0),
544
650
  db_record_offset(0),
550
656
  error(0),
551
657
  open_errno(0),
552
658
  errarg(0),
 
659
  column_bitmap_size(0),
553
660
  blob_ptr_size(0),
554
661
  db_low_byte_first(false),
 
662
  name_lock(false),
 
663
  replace_with_name_lock(false),
 
664
  waiting_on_cond(false),
555
665
  keys_in_use(0),
556
666
  keys_for_keyread(0),
557
 
  event_observers(NULL)
 
667
  event_observers(NULL),
 
668
  newed(true)
558
669
{
 
670
  memset(&name_hash, 0, sizeof(HASH));
 
671
 
559
672
  table_charset= 0;
560
673
  memset(&db, 0, sizeof(LEX_STRING));
561
674
  memset(&table_name, 0, sizeof(LEX_STRING));
568
681
  memcpy(&private_normalized_path[0], identifier.getPath().c_str(), identifier.getPath().size());
569
682
 
570
683
  {
 
684
    memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
571
685
    table_category=         TABLE_CATEGORY_TEMPORARY;
572
686
    tmp_table=              message::Table::INTERNAL;
573
 
    db.str= const_cast<char *>(private_key_for_cache.vector());
574
 
    db.length= strlen(private_key_for_cache.vector());
 
687
    db.str= &private_key_for_cache[0];
 
688
    db.length= strlen(&private_key_for_cache[0]);
575
689
    table_name.str= db.str + 1;
576
690
    table_name.length= strlen(table_name.str);
577
691
    path.str= &private_normalized_path[0];
584
698
/*
585
699
  Used for shares that will go into the cache.
586
700
*/
587
 
TableShare::TableShare(const TableIdentifier::Type type_arg,
588
 
                       const TableIdentifier &identifier,
 
701
TableShare::TableShare(TableIdentifier::Type type_arg,
 
702
                       TableIdentifier &identifier,
589
703
                       char *path_arg,
590
704
                       uint32_t path_length_arg) :
591
705
  table_category(TABLE_UNKNOWN_CATEGORY),
 
706
  open_count(0),
592
707
  found_next_number_field(NULL),
593
708
  timestamp_field(NULL),
594
709
  key_info(NULL),
595
 
  mem_root(TABLE_ALLOC_BLOCK_SIZE),
596
 
  all_set(),
 
710
  blob_field(NULL),
597
711
  block_size(0),
598
712
  version(0),
599
713
  timestamp_offset(0),
600
714
  reclength(0),
601
715
  stored_rec_length(0),
 
716
  row_type(ROW_TYPE_DEFAULT),
602
717
  max_rows(0),
603
718
  table_proto(NULL),
604
719
  storage_engine(NULL),
616
731
  uniques(0),
617
732
  null_fields(0),
618
733
  blob_fields(0),
619
 
  has_variable_width(false),
 
734
  timestamp_field_offset(0),
 
735
  varchar_fields(0),
620
736
  db_create_options(0),
621
737
  db_options_in_use(0),
622
738
  db_record_offset(0),
628
744
  error(0),
629
745
  open_errno(0),
630
746
  errarg(0),
 
747
  column_bitmap_size(0),
631
748
  blob_ptr_size(0),
632
749
  db_low_byte_first(false),
 
750
  name_lock(false),
 
751
  replace_with_name_lock(false),
 
752
  waiting_on_cond(false),
633
753
  keys_in_use(0),
634
754
  keys_for_keyread(0),
635
 
  event_observers(NULL)
 
755
  event_observers(NULL),
 
756
  newed(true)
636
757
{
 
758
  memset(&name_hash, 0, sizeof(HASH));
 
759
 
637
760
  table_charset= 0;
638
761
  memset(&db, 0, sizeof(LEX_STRING));
639
762
  memset(&table_name, 0, sizeof(LEX_STRING));
640
763
  memset(&path, 0, sizeof(LEX_STRING));
641
764
  memset(&normalized_path, 0, sizeof(LEX_STRING));
642
765
 
 
766
  mem_root.init_alloc_root(TABLE_ALLOC_BLOCK_SIZE);
643
767
  char *path_buff;
644
768
  std::string _path;
645
769
 
648
772
    Let us use the fact that the key is "db/0/table_name/0" + optional
649
773
    part for temporary tables.
650
774
  */
651
 
  db.str= const_cast<char *>(private_key_for_cache.vector());
 
775
  db.str= &private_key_for_cache[0];
652
776
  db.length=         strlen(db.str);
653
777
  table_name.str=    db.str + db.length + 1;
654
778
  table_name.length= strlen(table_name.str);
662
786
    TableIdentifier::build_table_filename(_path, db.str, table_name.str, false);
663
787
  }
664
788
 
665
 
  if ((path_buff= (char *)mem_root.alloc_root(_path.length() + 1)))
 
789
  if (mem_root.multi_alloc_root(0,
 
790
                                &path_buff, _path.length() + 1,
 
791
                                NULL))
666
792
  {
667
793
    setPath(path_buff, _path.length());
668
794
    strcpy(path_buff, _path.c_str());
669
795
    setNormalizedPath(path_buff, _path.length());
670
796
 
671
797
    version= refresh_version;
 
798
 
 
799
    pthread_mutex_init(&mutex, MY_MUTEX_INIT_FAST);
 
800
    pthread_cond_init(&cond, NULL);
672
801
  }
673
802
  else
674
803
  {
675
804
    assert(0); // We should throw here.
676
 
    abort();
677
805
  }
 
806
 
 
807
  newed= true;
678
808
}
679
809
 
680
810
void TableShare::init(const char *new_table_name,
681
811
                      const char *new_path)
682
812
{
683
813
 
 
814
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
684
815
  table_category=         TABLE_CATEGORY_TEMPORARY;
685
816
  tmp_table=              message::Table::INTERNAL;
686
817
  db.str= (char *)"";
696
827
{
697
828
  assert(ref_count == 0);
698
829
 
 
830
  /*
 
831
    If someone is waiting for this to be deleted, inform it about this.
 
832
    Don't do a delete until we know that no one is refering to this anymore.
 
833
  */
 
834
  if (tmp_table == message::Table::STANDARD)
 
835
  {
 
836
    /* share->mutex is locked in release_table_share() */
 
837
    while (waiting_on_cond)
 
838
    {
 
839
      pthread_cond_broadcast(&cond);
 
840
      pthread_cond_wait(&cond, &mutex);
 
841
    }
 
842
    /* No thread refers to this anymore */
 
843
    pthread_mutex_unlock(&mutex);
 
844
    pthread_mutex_destroy(&mutex);
 
845
    pthread_cond_destroy(&cond);
 
846
  }
 
847
  hash_free(&name_hash);
 
848
 
699
849
  storage_engine= NULL;
700
850
 
701
851
  delete table_proto;
702
852
  table_proto= NULL;
703
853
 
704
 
  plugin::EventObserver::deregisterTableEvents(*this);
705
 
 
706
854
  mem_root.free_root(MYF(0));                 // Free's share
707
855
}
708
856
 
709
 
void TableShare::setIdentifier(const TableIdentifier &identifier_arg)
 
857
void TableShare::setIdentifier(TableIdentifier &identifier_arg)
710
858
{
 
859
  private_key_for_cache.clear();
711
860
  private_key_for_cache= identifier_arg.getKey();
712
861
 
713
862
  /*
714
863
    Let us use the fact that the key is "db/0/table_name/0" + optional
715
864
    part for temporary tables.
716
865
  */
717
 
  db.str= const_cast<char *>(private_key_for_cache.vector());
 
866
  db.str= &private_key_for_cache[0];
718
867
  db.length=         strlen(db.str);
719
868
  table_name.str=    db.str + db.length + 1;
720
869
  table_name.length= strlen(table_name.str);
754
903
  db_create_options= (local_db_create_options & 0x0000FFFF);
755
904
  db_options_in_use= db_create_options;
756
905
 
 
906
  row_type= table_options.has_row_type() ?
 
907
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
 
908
 
757
909
  block_size= table_options.has_block_size() ?
758
910
    table_options.block_size() : 0;
759
911
 
760
 
  table_charset= get_charset(table_options.collation_id());
 
912
  table_charset= get_charset(table_options.has_collation_id()?
 
913
                                    table_options.collation_id() : 0);
761
914
 
762
 
  if (! table_charset)
 
915
  if (!table_charset)
763
916
  {
764
 
    char errmsg[100];
765
 
    snprintf(errmsg, sizeof(errmsg),
766
 
             _("Table %s has invalid/unknown collation: %d,%s"),
767
 
             getPath(),
768
 
             table_options.collation_id(),
769
 
             table_options.collation().c_str());
770
 
    errmsg[99]='\0';
771
 
 
772
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), errmsg);
773
 
    return ER_CORRUPT_TABLE_DEFINITION;
 
917
    /* unknown charset in head[38] or pre-3.23 frm */
 
918
    if (use_mb(default_charset_info))
 
919
    {
 
920
      /* Warn that we may be changing the size of character columns */
 
921
      errmsg_printf(ERRMSG_LVL_WARN,
 
922
                    _("'%s' had no or invalid character set, "
 
923
                      "and default character set is multi-byte, "
 
924
                      "so character column sizes may have changed"),
 
925
                    getPath());
 
926
    }
 
927
    table_charset= default_charset_info;
774
928
  }
775
929
 
776
930
  db_record_offset= 1;
882
1036
 
883
1037
      key_part->length= part.compare_length();
884
1038
 
885
 
      int mbmaxlen= 1;
886
 
 
887
 
      if (table.field(part.fieldnr()).type() == message::Table::Field::VARCHAR
888
 
          || table.field(part.fieldnr()).type() == message::Table::Field::BLOB)
889
 
      {
890
 
        uint32_t collation_id;
891
 
 
892
 
        if (table.field(part.fieldnr()).string_options().has_collation_id())
893
 
          collation_id= table.field(part.fieldnr()).string_options().collation_id();
894
 
        else
895
 
          collation_id= table.options().collation_id();
896
 
 
897
 
        const CHARSET_INFO *cs= get_charset(collation_id);
898
 
 
899
 
        mbmaxlen= cs->mbmaxlen;
900
 
      }
901
 
      key_part->length*= mbmaxlen;
902
 
 
903
1039
      key_part->store_length= key_part->length;
904
1040
 
905
1041
      /* key_part->offset is set later */
934
1070
  uint32_t local_null_fields= 0;
935
1071
  reclength= 0;
936
1072
 
937
 
  std::vector<uint32_t> field_offsets;
938
 
  std::vector<uint32_t> field_pack_length;
 
1073
  vector<uint32_t> field_offsets;
 
1074
  vector<uint32_t> field_pack_length;
939
1075
 
940
1076
  field_offsets.resize(fields);
941
1077
  field_pack_length.resize(fields);
981
1117
      {
982
1118
        message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
983
1119
 
984
 
        field_pack_length[fieldnr]= 4;
 
1120
        field_pack_length[fieldnr]=
 
1121
          get_enum_pack_length(field_options.field_value_size());
985
1122
 
986
1123
        interval_count++;
987
1124
        interval_parts+= field_options.field_value_size();
1106
1243
 
1107
1244
  bool use_hash= fields >= MAX_FIELDS_BEFORE_HASH;
1108
1245
 
 
1246
  if (use_hash)
 
1247
    use_hash= ! hash_init(&name_hash,
 
1248
                          system_charset_info,
 
1249
                          fields,
 
1250
                          0,
 
1251
                          0,
 
1252
                          (hash_get_key) get_field_name,
 
1253
                          0,
 
1254
                          0);
 
1255
 
1109
1256
  unsigned char* null_pos= getDefaultValues();
1110
1257
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
1111
1258
 
1122
1269
    }
1123
1270
 
1124
1271
    if (pfield.has_options() &&
1125
 
        pfield.options().has_default_expression() &&
1126
 
        pfield.options().default_expression().compare("CURRENT_TIMESTAMP") == 0)
 
1272
        pfield.options().has_default_value() &&
 
1273
        pfield.options().default_value().compare("NOW()") == 0)
1127
1274
    {
1128
 
      if (pfield.options().has_update_expression() &&
1129
 
          pfield.options().update_expression().compare("CURRENT_TIMESTAMP") == 0)
 
1275
      if (pfield.options().has_update_value() &&
 
1276
          pfield.options().update_value().compare("NOW()") == 0)
1130
1277
      {
1131
1278
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
1132
1279
      }
1133
 
      else if (! pfield.options().has_update_expression())
 
1280
      else if (! pfield.options().has_update_value())
1134
1281
      {
1135
1282
        unireg_type= Field::TIMESTAMP_DN_FIELD;
1136
1283
      }
1137
1284
      else
1138
 
      {
1139
 
        assert(0); // Invalid update value.
1140
 
        abort();
1141
 
      }
 
1285
        assert(1); // Invalid update value.
1142
1286
    }
1143
1287
    else if (pfield.has_options() &&
1144
 
             pfield.options().has_update_expression() &&
1145
 
             pfield.options().update_expression().compare("CURRENT_TIMESTAMP") == 0)
 
1288
             pfield.options().has_update_value() &&
 
1289
             pfield.options().update_value().compare("NOW()") == 0)
1146
1290
    {
1147
1291
      unireg_type= Field::TIMESTAMP_UN_FIELD;
1148
1292
    }
1220
1364
    Item *default_value= NULL;
1221
1365
 
1222
1366
    if (pfield.options().has_default_value() ||
1223
 
        pfield.options().default_null()  ||
 
1367
        pfield.options().has_default_null()  ||
1224
1368
        pfield.options().has_default_bin_value())
1225
1369
    {
1226
1370
      default_value= default_value_item(field_type,
1231
1375
    }
1232
1376
 
1233
1377
 
1234
 
    blob_ptr_size= portable_sizeof_char_ptr;
 
1378
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
 
1379
    memset(&temp_table, 0, sizeof(temp_table));
 
1380
    temp_table.setShare(this);
 
1381
    temp_table.in_use= &session;
 
1382
    temp_table.getMutableShare()->db_low_byte_first= true; //Cursor->low_byte_first();
 
1383
    temp_table.getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
1235
1384
 
1236
1385
    uint32_t field_length= 0; //Assignment is for compiler complaint.
1237
1386
 
1315
1464
    case DRIZZLE_TYPE_LONGLONG:
1316
1465
      field_length= MAX_BIGINT_WIDTH;
1317
1466
      break;
1318
 
    case DRIZZLE_TYPE_UUID:
1319
 
      field_length= field::Uuid::max_string_length();
1320
 
      break;
1321
1467
    case DRIZZLE_TYPE_NULL:
1322
1468
      abort(); // Programming error
1323
1469
    }
1324
1470
 
1325
 
    assert(enum_field_types_size == 12);
1326
 
 
1327
1471
    Field* f= make_field(record + field_offsets[fieldnr] + data_offset,
1328
 
                         field_length,
1329
 
                         pfield.constraints().is_nullable(),
1330
 
                         null_pos,
1331
 
                         null_bit_pos,
1332
 
                         decimals,
1333
 
                         field_type,
1334
 
                         charset,
1335
 
                         MTYP_TYPENR(unireg_type),
1336
 
                         ((field_type == DRIZZLE_TYPE_ENUM) ?  &intervals[interval_nr++] : (TYPELIB*) 0),
1337
 
                         getTableProto()->field(fieldnr).name().c_str());
 
1472
                                field_length,
 
1473
                                pfield.constraints().is_nullable(),
 
1474
                                null_pos,
 
1475
                                null_bit_pos,
 
1476
                                decimals,
 
1477
                                field_type,
 
1478
                                charset,
 
1479
                                (Field::utype) MTYP_TYPENR(unireg_type),
 
1480
                                ((field_type == DRIZZLE_TYPE_ENUM) ?
 
1481
                                 &intervals[interval_nr++]
 
1482
                                 : (TYPELIB*) 0),
 
1483
                                getTableProto()->field(fieldnr).name().c_str());
1338
1484
 
1339
1485
    field[fieldnr]= f;
1340
1486
 
1341
 
    // Insert post make_field code here.
1342
 
    switch (field_type)
1343
 
    {
1344
 
    case DRIZZLE_TYPE_BLOB:
1345
 
    case DRIZZLE_TYPE_VARCHAR:
1346
 
    case DRIZZLE_TYPE_DOUBLE:
1347
 
    case DRIZZLE_TYPE_DECIMAL:
1348
 
    case DRIZZLE_TYPE_TIMESTAMP:
1349
 
    case DRIZZLE_TYPE_DATETIME:
1350
 
    case DRIZZLE_TYPE_DATE:
1351
 
    case DRIZZLE_TYPE_ENUM:
1352
 
    case DRIZZLE_TYPE_LONG:
1353
 
    case DRIZZLE_TYPE_LONGLONG:
1354
 
    case DRIZZLE_TYPE_NULL:
1355
 
    case DRIZZLE_TYPE_UUID:
1356
 
      break;
1357
 
    }
1358
 
 
1359
 
    // This needs to go, we should be setting the "use" on the field so that
1360
 
    // it does not reference the share/table.
1361
 
    table::Shell temp_table(*this); /* Use this so that BLOB DEFAULT '' works */
1362
 
    temp_table.in_use= &session;
1363
 
 
1364
1487
    f->init(&temp_table); /* blob default values need table obj */
1365
1488
 
1366
1489
    if (! (f->flags & NOT_NULL_FLAG))
1385
1508
        return local_error;
1386
1509
      }
1387
1510
    }
1388
 
    else if (f->real_type() == DRIZZLE_TYPE_ENUM && (f->flags & NOT_NULL_FLAG))
 
1511
    else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
 
1512
             (f->flags & NOT_NULL_FLAG))
1389
1513
    {
1390
1514
      f->set_notnull();
1391
1515
      f->store((int64_t) 1, true);
1396
1520
    }
1397
1521
 
1398
1522
    /* hack to undo f->init() */
1399
 
    f->setTable(NULL);
 
1523
    f->table= NULL;
1400
1524
    f->orig_table= NULL;
1401
1525
 
1402
 
    f->setPosition(fieldnr);
 
1526
    f->field_index= fieldnr;
1403
1527
    f->comment= comment;
1404
1528
    if (! default_value &&
1405
1529
        ! (f->unireg_check==Field::NEXT_NUMBER) &&
1412
1536
    if (f->unireg_check == Field::NEXT_NUMBER)
1413
1537
      found_next_number_field= &(field[fieldnr]);
1414
1538
 
 
1539
    if (timestamp_field == f)
 
1540
      timestamp_field_offset= fieldnr;
 
1541
 
1415
1542
    if (use_hash) /* supposedly this never fails... but comments lie */
1416
 
    {
1417
 
      const char *local_field_name= field[fieldnr]->field_name;
1418
 
      name_hash.insert(make_pair(local_field_name, &(field[fieldnr])));
1419
 
    }
 
1543
      (void) my_hash_insert(&name_hash,
 
1544
                            (unsigned char*)&(field[fieldnr]));
 
1545
 
1420
1546
  }
1421
1547
 
1422
1548
  keyinfo= key_info;
1441
1567
    We need to set the unused bits to 1. If the number of bits is a multiple
1442
1568
    of 8 there are no unused bits.
1443
1569
  */
 
1570
 
1444
1571
  if (null_count & 7)
1445
1572
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1446
1573
 
1606
1733
 
1607
1734
  if (blob_fields)
1608
1735
  {
 
1736
    uint32_t k, *save;
 
1737
 
1609
1738
    /* Store offsets to blob fields to find them fast */
1610
1739
    blob_field.resize(blob_fields);
1611
 
    uint32_t *save= &blob_field[0];
1612
 
    uint32_t k= 0;
 
1740
    save= &blob_field[0];
 
1741
    k= 0;
1613
1742
    for (Fields::iterator iter= field.begin(); iter != field.end()-1; iter++, k++)
1614
1743
    {
1615
1744
      if ((*iter)->flags & BLOB_FLAG)
1617
1746
    }
1618
1747
  }
1619
1748
 
1620
 
  all_set.clear();
1621
 
  all_set.resize(fields);
1622
 
  all_set.set();
 
1749
  db_low_byte_first= true; // @todo Question this.
 
1750
  column_bitmap_size= bitmap_buffer_size(fields);
 
1751
 
 
1752
  all_bitmap.resize(column_bitmap_size);
 
1753
  all_set.init(&all_bitmap[0], fields);
 
1754
  all_set.setAll();
1623
1755
 
1624
1756
  return local_error;
1625
1757
}
1634
1766
  error= local_error;
1635
1767
  open_errno= errno;
1636
1768
  errarg= 0;
 
1769
  hash_free(&name_hash);
1637
1770
  open_table_error(local_error, open_errno, 0);
1638
1771
 
1639
1772
  return local_error;
1650
1783
 
1651
1784
  NOTES
1652
1785
  This function is called when the table definition is not cached in
1653
 
  definition::Cache::singleton().getCache()
 
1786
  table_def_cache
1654
1787
  The data is returned in 'share', which is alloced by
1655
1788
  alloc_table_share().. The code assumes that share is initialized.
1656
1789
 
1664
1797
  6    Unknown .frm version
1665
1798
*/
1666
1799
 
1667
 
int TableShare::open_table_def(Session& session, const TableIdentifier &identifier)
 
1800
int TableShare::open_table_def(Session& session, TableIdentifier &identifier)
1668
1801
{
1669
1802
  int local_error;
1670
1803
  bool error_given;
1672
1805
  local_error= 1;
1673
1806
  error_given= 0;
1674
1807
 
1675
 
  message::table::shared_ptr table;
 
1808
  message::Table table;
1676
1809
 
1677
1810
  local_error= plugin::StorageEngine::getTableDefinition(session, identifier, table);
1678
1811
 
1685
1818
    }
1686
1819
    else
1687
1820
    {
1688
 
      if (not table->IsInitialized())
 
1821
      if (not table.IsInitialized())
1689
1822
      {
1690
1823
        local_error= 4;
1691
1824
      }
1693
1826
    goto err_not_open;
1694
1827
  }
1695
1828
 
1696
 
  local_error= parse_table_proto(session, *table);
 
1829
  local_error= parse_table_proto(session, table);
1697
1830
 
1698
1831
  setTableCategory(TABLE_CATEGORY_USER);
1699
1832
 
1731
1864
  5    Error (see open_table_error: charset unavailable)
1732
1865
  7    Table definition has changed in engine
1733
1866
*/
 
1867
 
1734
1868
int TableShare::open_table_from_share(Session *session,
1735
1869
                                      const TableIdentifier &identifier,
1736
1870
                                      const char *alias,
1737
1871
                                      uint32_t db_stat, uint32_t ha_open_flags,
1738
1872
                                      Table &outparam)
1739
1873
{
 
1874
  int local_error;
 
1875
  uint32_t records, bitmap_size;
1740
1876
  bool error_reported= false;
1741
 
  int ret= open_table_from_share_inner(session, alias, db_stat, outparam);
1742
 
 
1743
 
  if (not ret)
1744
 
    ret= open_table_cursor_inner(identifier, db_stat, ha_open_flags, outparam, error_reported);
1745
 
 
1746
 
  if (not ret)
1747
 
    return ret;
1748
 
 
1749
 
  if (not error_reported)
1750
 
    open_table_error(ret, errno, 0);
1751
 
 
1752
 
  delete outparam.cursor;
1753
 
  outparam.cursor= 0;                           // For easier error checking
1754
 
  outparam.db_stat= 0;
1755
 
  outparam.getMemRoot()->free_root(MYF(0));       // Safe to call on zeroed root
1756
 
  outparam.clearAlias();
1757
 
 
1758
 
  return ret;
1759
 
}
1760
 
 
1761
 
int TableShare::open_table_from_share_inner(Session *session,
1762
 
                                            const char *alias,
1763
 
                                            uint32_t db_stat,
1764
 
                                            Table &outparam)
1765
 
{
1766
 
  int local_error;
1767
 
  uint32_t records;
1768
 
  unsigned char *record= NULL;
 
1877
  unsigned char *record, *bitmaps;
1769
1878
  Field **field_ptr;
1770
1879
 
1771
1880
  /* Parsing of partitioning information from .frm needs session->lex set up. */
1774
1883
  local_error= 1;
1775
1884
  outparam.resetTable(session, this, db_stat);
1776
1885
 
1777
 
  outparam.setAlias(alias);
 
1886
 
 
1887
  if (not (outparam.alias= strdup(alias)))
 
1888
    goto err;
1778
1889
 
1779
1890
  /* Allocate Cursor */
1780
 
  if (not (outparam.cursor= db_type()->getCursor(outparam)))
1781
 
    return local_error;
 
1891
  if (not (outparam.cursor= db_type()->getCursor(*this, outparam.getMemRoot())))
 
1892
    goto err;
1782
1893
 
1783
1894
  local_error= 4;
1784
1895
  records= 0;
1788
1899
  records++;
1789
1900
 
1790
1901
  if (!(record= (unsigned char*) outparam.alloc_root(rec_buff_length * records)))
1791
 
    return local_error;
 
1902
    goto err;
1792
1903
 
1793
1904
  if (records == 0)
1794
1905
  {
1801
1912
    if (records > 1)
1802
1913
      outparam.record[1]= record+ rec_buff_length;
1803
1914
    else
1804
 
      outparam.record[1]= outparam.getInsertRecord();   // Safety
 
1915
      outparam.record[1]= outparam.record[0];   // Safety
1805
1916
  }
1806
1917
 
1807
 
#ifdef HAVE_VALGRIND
 
1918
#ifdef HAVE_purify
1808
1919
  /*
1809
1920
    We need this because when we read var-length rows, we are not updating
1810
1921
    bytes after end of varchar
1811
1922
  */
1812
1923
  if (records > 1)
1813
1924
  {
1814
 
    memcpy(outparam.getInsertRecord(), getDefaultValues(), rec_buff_length);
1815
 
    memcpy(outparam.getUpdateRecord(), getDefaultValues(), null_bytes);
 
1925
    memcpy(outparam.record[0], getDefaultValues(), rec_buff_length);
 
1926
    memcpy(outparam.record[1], getDefaultValues(), null_bytes);
1816
1927
    if (records > 2)
1817
 
      memcpy(outparam.getUpdateRecord(), getDefaultValues(), rec_buff_length);
 
1928
      memcpy(outparam.record[1], getDefaultValues(), rec_buff_length);
1818
1929
  }
1819
1930
#endif
1820
1931
  if (records > 1)
1821
1932
  {
1822
 
    memcpy(outparam.getUpdateRecord(), getDefaultValues(), null_bytes);
 
1933
    memcpy(outparam.record[1], getDefaultValues(), null_bytes);
1823
1934
  }
1824
1935
 
1825
1936
  if (!(field_ptr = (Field **) outparam.alloc_root( (uint32_t) ((fields+1)* sizeof(Field*)))))
1826
1937
  {
1827
 
    return local_error;
 
1938
    goto err;
1828
1939
  }
1829
1940
 
1830
1941
  outparam.setFields(field_ptr);
1831
1942
 
1832
 
  record= (unsigned char*) outparam.getInsertRecord()-1;        /* Fieldstart = 1 */
 
1943
  record= (unsigned char*) outparam.record[0]-1;        /* Fieldstart = 1 */
1833
1944
 
1834
1945
  outparam.null_flags= (unsigned char*) record+1;
1835
1946
 
1837
1948
  for (uint32_t i= 0 ; i < fields; i++, field_ptr++)
1838
1949
  {
1839
1950
    if (!((*field_ptr)= field[i]->clone(outparam.getMemRoot(), &outparam)))
1840
 
      return local_error;
 
1951
      goto err;
1841
1952
  }
1842
1953
  (*field_ptr)= 0;                              // End marker
1843
1954
 
1845
1956
    outparam.found_next_number_field=
1846
1957
      outparam.getField(positionFields(found_next_number_field));
1847
1958
  if (timestamp_field)
1848
 
    outparam.timestamp_field= (Field_timestamp*) outparam.getField(timestamp_field->position());
 
1959
    outparam.timestamp_field= (Field_timestamp*) outparam.getField(timestamp_field_offset);
 
1960
 
1849
1961
 
1850
1962
  /* Fix key->name and key_part->field */
1851
1963
  if (key_parts)
1855
1967
    uint32_t n_length;
1856
1968
    n_length= keys*sizeof(KeyInfo) + key_parts*sizeof(KeyPartInfo);
1857
1969
    if (!(local_key_info= (KeyInfo*) outparam.alloc_root(n_length)))
1858
 
      return local_error;
 
1970
      goto err;
1859
1971
    outparam.key_info= local_key_info;
1860
1972
    key_part= (reinterpret_cast<KeyPartInfo*> (local_key_info+keys));
1861
1973
 
1894
2006
 
1895
2007
  /* Allocate bitmaps */
1896
2008
 
1897
 
  outparam.def_read_set.resize(fields);
1898
 
  outparam.def_write_set.resize(fields);
1899
 
  outparam.tmp_set.resize(fields);
 
2009
  bitmap_size= column_bitmap_size;
 
2010
  if (!(bitmaps= (unsigned char*) outparam.alloc_root(bitmap_size*3)))
 
2011
  {
 
2012
    goto err;
 
2013
  }
 
2014
  outparam.def_read_set.init((my_bitmap_map*) bitmaps, fields);
 
2015
  outparam.def_write_set.init((my_bitmap_map*) (bitmaps+bitmap_size), fields);
 
2016
  outparam.tmp_set.init((my_bitmap_map*) (bitmaps+bitmap_size*2), fields);
1900
2017
  outparam.default_column_bitmaps();
1901
2018
 
1902
 
  return 0;
1903
 
}
1904
 
 
1905
 
int TableShare::open_table_cursor_inner(const TableIdentifier &identifier,
1906
 
                                        uint32_t db_stat, uint32_t ha_open_flags,
1907
 
                                        Table &outparam,
1908
 
                                        bool &error_reported)
1909
 
{
1910
2019
  /* The table struct is now initialized;  Open the table */
1911
 
  int local_error= 2;
 
2020
  local_error= 2;
1912
2021
  if (db_stat)
1913
2022
  {
1914
2023
    assert(!(db_stat & HA_WAIT_IF_LOCKED));
1915
2024
    int ha_err;
1916
2025
 
1917
 
    if ((ha_err= (outparam.cursor->ha_open(identifier,
1918
 
                                           (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1919
 
                                           (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
 
2026
    if ((ha_err= (outparam.cursor->ha_open(identifier, &outparam, getNormalizedPath(),
 
2027
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
 
2028
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1920
2029
    {
1921
2030
      switch (ha_err)
1922
2031
      {
1943
2052
          local_error= 7;
1944
2053
        break;
1945
2054
      }
1946
 
      return local_error;
 
2055
      goto err;
1947
2056
    }
1948
2057
  }
1949
2058
 
 
2059
#if defined(HAVE_purify)
 
2060
  memset(bitmaps, 0, bitmap_size*3);
 
2061
#endif
 
2062
 
1950
2063
  return 0;
 
2064
 
 
2065
err:
 
2066
  if (!error_reported)
 
2067
    open_table_error(local_error, errno, 0);
 
2068
 
 
2069
  delete outparam.cursor;
 
2070
  outparam.cursor= 0;                           // For easier error checking
 
2071
  outparam.db_stat= 0;
 
2072
  outparam.getMemRoot()->free_root(MYF(0));       // Safe to call on zeroed root
 
2073
  free((char*) outparam.alias);
 
2074
  return (local_error);
1951
2075
}
1952
2076
 
1953
2077
/* error message when opening a form cursor */
2037
2161
  case DRIZZLE_TYPE_DATE:
2038
2162
  case DRIZZLE_TYPE_DATETIME:
2039
2163
  case DRIZZLE_TYPE_TIMESTAMP:
2040
 
  case DRIZZLE_TYPE_UUID:
2041
2164
    field_charset= &my_charset_bin;
2042
2165
  default: break;
2043
2166
  }
2050
2173
                                 null_pos,
2051
2174
                                 null_bit,
2052
2175
                                 field_name,
 
2176
                                 get_enum_pack_length(interval->count),
2053
2177
                                 interval,
2054
2178
                                 field_charset);
2055
2179
  case DRIZZLE_TYPE_VARCHAR:
2056
 
    setVariableWidth();
2057
2180
    return new (&mem_root) Field_varstring(ptr,field_length,
2058
 
                                      ha_varchar_packlength(field_length),
 
2181
                                      HA_VARCHAR_PACKLENGTH(field_length),
2059
2182
                                      null_pos,null_bit,
2060
2183
                                      field_name,
 
2184
                                      this,
2061
2185
                                      field_charset);
2062
2186
  case DRIZZLE_TYPE_BLOB:
2063
2187
    return new (&mem_root) Field_blob(ptr,
2065
2189
                                 null_bit,
2066
2190
                                 field_name,
2067
2191
                                 this,
 
2192
                                 calc_pack_length(DRIZZLE_TYPE_LONG, 0),
2068
2193
                                 field_charset);
2069
2194
  case DRIZZLE_TYPE_DECIMAL:
2070
2195
    return new (&mem_root) Field_decimal(ptr,
2086
2211
                                   decimals,
2087
2212
                                   false,
2088
2213
                                   false /* is_unsigned */);
2089
 
  case DRIZZLE_TYPE_UUID:
2090
 
    return new (&mem_root) field::Uuid(ptr,
2091
 
                                       field_length,
2092
 
                                       null_pos,
2093
 
                                       null_bit,
2094
 
                                       field_name);
2095
2214
  case DRIZZLE_TYPE_LONG:
2096
 
    return new (&mem_root) field::Int32(ptr,
2097
 
                                        field_length,
2098
 
                                        null_pos,
2099
 
                                        null_bit,
2100
 
                                        unireg_check,
2101
 
                                        field_name);
 
2215
    return new (&mem_root) Field_long(ptr,
 
2216
                                 field_length,
 
2217
                                 null_pos,
 
2218
                                 null_bit,
 
2219
                                 unireg_check,
 
2220
                                 field_name,
 
2221
                                 false,
 
2222
                                 false /* is_unsigned */);
2102
2223
  case DRIZZLE_TYPE_LONGLONG:
2103
 
    return new (&mem_root) field::Int64(ptr,
2104
 
                                        field_length,
2105
 
                                        null_pos,
2106
 
                                        null_bit,
2107
 
                                        unireg_check,
2108
 
                                        field_name);
 
2224
    return new (&mem_root) Field_int64_t(ptr,
 
2225
                                    field_length,
 
2226
                                    null_pos,
 
2227
                                    null_bit,
 
2228
                                    unireg_check,
 
2229
                                    field_name,
 
2230
                                    false,
 
2231
                                    false /* is_unsigned */);
2109
2232
  case DRIZZLE_TYPE_TIMESTAMP:
2110
2233
    return new (&mem_root) Field_timestamp(ptr,
2111
2234
                                      field_length,
2132
2255
                                 field_length,
2133
2256
                                 field_name,
2134
2257
                                 field_charset);
 
2258
  default: // Impossible (Wrong version)
 
2259
    break;
2135
2260
  }
2136
 
  assert(0);
2137
 
  abort();
 
2261
  return 0;
2138
2262
}
2139
2263
 
2140
2264