~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_share.cc

  • Committer: Brian Aker
  • Date: 2010-10-19 08:17:10 UTC
  • mto: (1864.2.1 merge)
  • mto: This revision was merged to the branch mainline in revision 1864.
  • Revision ID: brian@tangent.org-20101019081710-hw13j03145h13pdg
Merge in a bit more strictness around table type.

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;
89
84
 
90
85
/*****************************************************************************
91
86
  Functions to handle table definition cach (TableShare)
92
87
 *****************************************************************************/
93
88
 
 
89
 
 
90
// @todo switch this a boost::thread one only call.
 
91
void TableShare::cacheStart(void)
 
92
{
 
93
  /* 
 
94
   * This is going to overalloc a bit - as rehash sets the number of
 
95
   * buckets, not the number of elements. BUT, it'll allow us to not need
 
96
   * to rehash later on as the unordered_map grows.
 
97
 */
 
98
  table_def_cache.rehash(table_def_size);
 
99
}
 
100
 
 
101
 
 
102
/**
 
103
 * @TODO This should return size_t
 
104
 */
 
105
uint32_t cached_table_definitions(void)
 
106
{
 
107
  return static_cast<uint32_t>(table_def_cache.size());
 
108
}
 
109
 
 
110
 
94
111
/*
95
112
  Mark that we are not using table share anymore.
96
113
 
106
123
void TableShare::release(TableShare *share)
107
124
{
108
125
  bool to_be_deleted= false;
109
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle);
 
126
  safe_mutex_assert_owner(LOCK_open.native_handle);
110
127
 
111
128
  share->lock();
112
129
  if (!--share->ref_count)
113
130
  {
114
131
    to_be_deleted= true;
115
132
  }
 
133
 
 
134
  if (to_be_deleted)
 
135
  {
 
136
    TableIdentifier identifier(share->getSchemaName(), share->getTableName());
 
137
    plugin::EventObserver::deregisterTableEvents(*share);
 
138
   
 
139
    TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
 
140
    if (iter != table_def_cache.end())
 
141
    {
 
142
      table_def_cache.erase(iter);
 
143
    }
 
144
    return;
 
145
  }
116
146
  share->unlock();
117
 
 
118
 
  if (to_be_deleted)
119
 
  {
120
 
    definition::Cache::singleton().erase(share->getCacheKey());
121
 
  }
122
147
}
123
148
 
124
 
void TableShare::release(TableShare::shared_ptr &share)
 
149
void TableShare::release(TableSharePtr &share)
125
150
{
126
151
  bool to_be_deleted= false;
127
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle);
 
152
  safe_mutex_assert_owner(LOCK_open.native_handle);
128
153
 
129
154
  share->lock();
130
155
  if (!--share->ref_count)
131
156
  {
132
157
    to_be_deleted= true;
133
158
  }
 
159
 
 
160
  if (to_be_deleted)
 
161
  {
 
162
    TableIdentifier identifier(share->getSchemaName(), share->getTableName());
 
163
    plugin::EventObserver::deregisterTableEvents(*share);
 
164
   
 
165
    TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
 
166
    if (iter != table_def_cache.end())
 
167
    {
 
168
      table_def_cache.erase(iter);
 
169
    }
 
170
    return;
 
171
  }
134
172
  share->unlock();
135
 
 
136
 
  if (to_be_deleted)
137
 
  {
138
 
    definition::Cache::singleton().erase(share->getCacheKey());
139
 
  }
140
173
}
141
174
 
142
 
void TableShare::release(const TableIdentifier &identifier)
 
175
void TableShare::release(TableIdentifier &identifier)
143
176
{
144
 
  TableShare::shared_ptr share= definition::Cache::singleton().find(identifier.getKey());
145
 
  if (share)
 
177
  TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
 
178
  if (iter != table_def_cache.end())
146
179
  {
 
180
    TableSharePtr share= (*iter).second;
147
181
    share->version= 0;                          // Mark for delete
148
182
    if (share->ref_count == 0)
149
183
    {
150
 
      definition::Cache::singleton().erase(identifier.getKey());
 
184
      share->lock();
 
185
      plugin::EventObserver::deregisterTableEvents(*share);
 
186
      table_def_cache.erase(identifier.getKey());
151
187
    }
152
188
  }
153
189
}
154
190
 
155
191
 
156
 
static TableShare::shared_ptr foundTableShare(TableShare::shared_ptr share)
 
192
static TableSharePtr foundTableShare(TableSharePtr share)
157
193
{
158
194
  /*
159
195
    We found an existing table definition. Return it if we didn't get
166
202
    /* Table definition contained an error */
167
203
    share->open_table_error(share->error, share->open_errno, share->errarg);
168
204
 
169
 
    return TableShare::shared_ptr();
 
205
    return TableSharePtr();
170
206
  }
171
207
 
172
208
  share->incrementTableCount();
189
225
  If it doesn't exist, create a new from the table definition file.
190
226
 
191
227
  NOTES
192
 
  We must have wrlock on table::Cache::singleton().mutex() when we come here
 
228
  We must have wrlock on LOCK_open when we come here
193
229
  (To be changed later)
194
230
 
195
231
  RETURN
197
233
#  Share for table
198
234
*/
199
235
 
200
 
TableShare::shared_ptr TableShare::getShareCreate(Session *session, 
201
 
                                                  const TableIdentifier &identifier,
202
 
                                                  int &in_error)
 
236
TableSharePtr TableShare::getShareCreate(Session *session, 
 
237
                                         TableIdentifier &identifier,
 
238
                                         int *error)
203
239
{
204
 
  TableShare::shared_ptr share;
 
240
  TableSharePtr share;
205
241
 
206
 
  in_error= 0;
 
242
  *error= 0;
207
243
 
208
244
  /* Read table definition from cache */
209
 
  if ((share= definition::Cache::singleton().find(identifier.getKey())))
 
245
  TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
 
246
  if (iter != table_def_cache.end())
 
247
  {
 
248
    share= (*iter).second;
210
249
    return foundTableShare(share);
 
250
  }
211
251
 
212
252
  share.reset(new TableShare(message::Table::STANDARD, identifier));
213
253
  
 
254
  /*
 
255
    Lock mutex to be able to read table definition from file without
 
256
    conflicts
 
257
  */
 
258
  share->lock();
 
259
 
 
260
  pair<TableDefinitionCache::iterator, bool> ret=
 
261
    table_def_cache.insert(make_pair(identifier.getKey(), share));
 
262
  if (ret.second == false)
 
263
  {
 
264
    return TableSharePtr();
 
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());
217
271
 
218
 
    return TableShare::shared_ptr();
 
272
    return TableSharePtr();
219
273
  }
220
274
  share->ref_count++;                           // Mark in use
221
275
  
222
276
  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();
 
277
  
 
278
  share->unlock();
228
279
 
229
280
  return share;
230
281
}
231
282
 
 
283
 
 
284
/*
 
285
  Check if table definition exits in cache
 
286
 
 
287
  SYNOPSIS
 
288
  get_cached_table_share()
 
289
  db                    Database name
 
290
  table_name            Table name
 
291
 
 
292
  RETURN
 
293
  0  Not cached
 
294
#  TableShare for table
 
295
*/
 
296
TableSharePtr TableShare::getShare(TableIdentifier &identifier)
 
297
{
 
298
  safe_mutex_assert_owner(LOCK_open.native_handle);
 
299
 
 
300
  TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
 
301
  if (iter != table_def_cache.end())
 
302
  {
 
303
    return (*iter).second;
 
304
  }
 
305
 
 
306
  return TableSharePtr();
 
307
}
 
308
 
232
309
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
233
310
{
234
311
  enum_field_types field_type;
265
342
  case message::Table::Field::BLOB:
266
343
    field_type= DRIZZLE_TYPE_BLOB;
267
344
    break;
268
 
  case message::Table::Field::UUID:
269
 
    field_type= DRIZZLE_TYPE_UUID;
270
 
    break;
271
345
  default:
272
 
    assert(0);
273
 
    abort(); // Programming error
 
346
    field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
 
347
    assert(1);
274
348
  }
275
349
 
276
350
  return field_type;
304
378
                                 default_value->length());
305
379
    break;
306
380
  case DRIZZLE_TYPE_NULL:
307
 
    assert(0);
308
 
    abort();
 
381
    assert(false);
309
382
  case DRIZZLE_TYPE_TIMESTAMP:
310
383
  case DRIZZLE_TYPE_DATETIME:
311
384
  case DRIZZLE_TYPE_DATE:
312
385
  case DRIZZLE_TYPE_ENUM:
313
 
  case DRIZZLE_TYPE_UUID:
314
386
    default_item= new Item_string(default_value->c_str(),
315
387
                                  default_value->length(),
316
388
                                  system_charset_info);
361
433
      size_t num_parts= index.index_part_size();
362
434
      for (size_t y= 0; y < num_parts; ++y)
363
435
      {
364
 
        if (index.index_part(y).fieldnr() == in_field->position())
 
436
        if (index.index_part(y).fieldnr() == in_field->field_index)
365
437
          return true;
366
438
      }
367
439
    }
369
441
  return false;
370
442
}
371
443
 
372
 
TableShare::TableShare(const TableIdentifier::Type type_arg) :
 
444
const TableDefinitionCache &TableShare::getCache()
 
445
{
 
446
  return table_def_cache;
 
447
}
 
448
 
 
449
TableShare::TableShare(TableIdentifier::Type type_arg) :
373
450
  table_category(TABLE_UNKNOWN_CATEGORY),
 
451
  open_count(0),
374
452
  found_next_number_field(NULL),
375
453
  timestamp_field(NULL),
376
454
  key_info(NULL),
398
476
  uniques(0),
399
477
  null_fields(0),
400
478
  blob_fields(0),
 
479
  timestamp_field_offset(0),
401
480
  has_variable_width(false),
402
481
  db_create_options(0),
403
482
  db_options_in_use(0),
412
491
  errarg(0),
413
492
  blob_ptr_size(0),
414
493
  db_low_byte_first(false),
 
494
  name_lock(false),
 
495
  replace_with_name_lock(false),
 
496
  waiting_on_cond(false),
415
497
  keys_in_use(0),
416
498
  keys_for_keyread(0),
417
499
  event_observers(NULL)
425
507
 
426
508
  if (type_arg == message::Table::INTERNAL)
427
509
  {
428
 
    TableIdentifier::build_tmptable_filename(private_key_for_cache.vectorPtr());
429
 
    init(private_key_for_cache.vector(), private_key_for_cache.vector());
 
510
    TableIdentifier::build_tmptable_filename(private_key_for_cache);
 
511
    init(&private_key_for_cache[0], &private_key_for_cache[0]);
430
512
  }
431
513
  else
432
514
  {
434
516
  }
435
517
}
436
518
 
437
 
TableShare::TableShare(const TableIdentifier &identifier, const TableIdentifier::Key &key) :// Used by placeholder
 
519
TableShare::TableShare(TableIdentifier &identifier, const TableIdentifier::Key &key) :// Used by placeholder
438
520
  table_category(TABLE_UNKNOWN_CATEGORY),
 
521
  open_count(0),
439
522
  found_next_number_field(NULL),
440
523
  timestamp_field(NULL),
441
524
  key_info(NULL),
463
546
  uniques(0),
464
547
  null_fields(0),
465
548
  blob_fields(0),
 
549
  timestamp_field_offset(0),
466
550
  has_variable_width(false),
467
551
  db_create_options(0),
468
552
  db_options_in_use(0),
477
561
  errarg(0),
478
562
  blob_ptr_size(0),
479
563
  db_low_byte_first(false),
 
564
  name_lock(false),
 
565
  replace_with_name_lock(false),
 
566
  waiting_on_cond(false),
480
567
  keys_in_use(0),
481
568
  keys_for_keyread(0),
482
569
  event_observers(NULL)
492
579
  table_category=         TABLE_CATEGORY_TEMPORARY;
493
580
  tmp_table=              message::Table::INTERNAL;
494
581
 
495
 
  db.str= const_cast<char *>(private_key_for_cache.vector());
496
 
  db.length= strlen(private_key_for_cache.vector());
 
582
  db.str= &private_key_for_cache[0];
 
583
  db.length= strlen(&private_key_for_cache[0]);
497
584
 
498
 
  table_name.str= const_cast<char *>(private_key_for_cache.vector()) + strlen(private_key_for_cache.vector()) + 1;
 
585
  table_name.str= &private_key_for_cache[0] + strlen(&private_key_for_cache[0]) + 1;
499
586
  table_name.length= strlen(table_name.str);
500
587
  path.str= (char *)"";
501
588
  normalized_path.str= path.str;
502
589
  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
 
 
 
590
  assert(strcmp(identifier.getTableName().c_str(), table_name.str) == 0);
508
591
  assert(strcmp(identifier.getSchemaName().c_str(), db.str) == 0);
509
592
}
510
593
 
511
594
 
512
595
TableShare::TableShare(const TableIdentifier &identifier) : // Just used during createTable()
513
596
  table_category(TABLE_UNKNOWN_CATEGORY),
 
597
  open_count(0),
514
598
  found_next_number_field(NULL),
515
599
  timestamp_field(NULL),
516
600
  key_info(NULL),
538
622
  uniques(0),
539
623
  null_fields(0),
540
624
  blob_fields(0),
 
625
  timestamp_field_offset(0),
541
626
  has_variable_width(false),
542
627
  db_create_options(0),
543
628
  db_options_in_use(0),
552
637
  errarg(0),
553
638
  blob_ptr_size(0),
554
639
  db_low_byte_first(false),
 
640
  name_lock(false),
 
641
  replace_with_name_lock(false),
 
642
  waiting_on_cond(false),
555
643
  keys_in_use(0),
556
644
  keys_for_keyread(0),
557
645
  event_observers(NULL)
570
658
  {
571
659
    table_category=         TABLE_CATEGORY_TEMPORARY;
572
660
    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());
 
661
    db.str= &private_key_for_cache[0];
 
662
    db.length= strlen(&private_key_for_cache[0]);
575
663
    table_name.str= db.str + 1;
576
664
    table_name.length= strlen(table_name.str);
577
665
    path.str= &private_normalized_path[0];
584
672
/*
585
673
  Used for shares that will go into the cache.
586
674
*/
587
 
TableShare::TableShare(const TableIdentifier::Type type_arg,
588
 
                       const TableIdentifier &identifier,
 
675
TableShare::TableShare(TableIdentifier::Type type_arg,
 
676
                       TableIdentifier &identifier,
589
677
                       char *path_arg,
590
678
                       uint32_t path_length_arg) :
591
679
  table_category(TABLE_UNKNOWN_CATEGORY),
 
680
  open_count(0),
592
681
  found_next_number_field(NULL),
593
682
  timestamp_field(NULL),
594
683
  key_info(NULL),
616
705
  uniques(0),
617
706
  null_fields(0),
618
707
  blob_fields(0),
 
708
  timestamp_field_offset(0),
619
709
  has_variable_width(false),
620
710
  db_create_options(0),
621
711
  db_options_in_use(0),
630
720
  errarg(0),
631
721
  blob_ptr_size(0),
632
722
  db_low_byte_first(false),
 
723
  name_lock(false),
 
724
  replace_with_name_lock(false),
 
725
  waiting_on_cond(false),
633
726
  keys_in_use(0),
634
727
  keys_for_keyread(0),
635
728
  event_observers(NULL)
648
741
    Let us use the fact that the key is "db/0/table_name/0" + optional
649
742
    part for temporary tables.
650
743
  */
651
 
  db.str= const_cast<char *>(private_key_for_cache.vector());
 
744
  db.str= &private_key_for_cache[0];
652
745
  db.length=         strlen(db.str);
653
746
  table_name.str=    db.str + db.length + 1;
654
747
  table_name.length= strlen(table_name.str);
673
766
  else
674
767
  {
675
768
    assert(0); // We should throw here.
676
 
    abort();
677
769
  }
678
770
}
679
771
 
696
788
{
697
789
  assert(ref_count == 0);
698
790
 
 
791
  /*
 
792
    If someone is waiting for this to be deleted, inform it about this.
 
793
    Don't do a delete until we know that no one is refering to this anymore.
 
794
  */
 
795
  if (tmp_table == message::Table::STANDARD)
 
796
  {
 
797
    /* share->mutex is locked in release_table_share() */
 
798
    while (waiting_on_cond)
 
799
    {
 
800
      cond.notify_all();
 
801
      boost::mutex::scoped_lock scoped(mutex, boost::adopt_lock_t());
 
802
      cond.wait(scoped);
 
803
      scoped.release();
 
804
    }
 
805
    /* No thread refers to this anymore */
 
806
    mutex.unlock();
 
807
  }
 
808
 
699
809
  storage_engine= NULL;
700
810
 
701
811
  delete table_proto;
702
812
  table_proto= NULL;
703
813
 
704
 
  plugin::EventObserver::deregisterTableEvents(*this);
705
 
 
706
814
  mem_root.free_root(MYF(0));                 // Free's share
707
815
}
708
816
 
709
 
void TableShare::setIdentifier(const TableIdentifier &identifier_arg)
 
817
void TableShare::setIdentifier(TableIdentifier &identifier_arg)
710
818
{
 
819
  private_key_for_cache.clear();
711
820
  private_key_for_cache= identifier_arg.getKey();
712
821
 
713
822
  /*
714
823
    Let us use the fact that the key is "db/0/table_name/0" + optional
715
824
    part for temporary tables.
716
825
  */
717
 
  db.str= const_cast<char *>(private_key_for_cache.vector());
 
826
  db.str= &private_key_for_cache[0];
718
827
  db.length=         strlen(db.str);
719
828
  table_name.str=    db.str + db.length + 1;
720
829
  table_name.length= strlen(table_name.str);
934
1043
  uint32_t local_null_fields= 0;
935
1044
  reclength= 0;
936
1045
 
937
 
  std::vector<uint32_t> field_offsets;
938
 
  std::vector<uint32_t> field_pack_length;
 
1046
  vector<uint32_t> field_offsets;
 
1047
  vector<uint32_t> field_pack_length;
939
1048
 
940
1049
  field_offsets.resize(fields);
941
1050
  field_pack_length.resize(fields);
1135
1244
        unireg_type= Field::TIMESTAMP_DN_FIELD;
1136
1245
      }
1137
1246
      else
1138
 
      {
1139
 
        assert(0); // Invalid update value.
1140
 
        abort();
1141
 
      }
 
1247
        assert(1); // Invalid update value.
1142
1248
    }
1143
1249
    else if (pfield.has_options() &&
1144
1250
             pfield.options().has_update_expression() &&
1231
1337
    }
1232
1338
 
1233
1339
 
 
1340
    db_low_byte_first= true; //Cursor->low_byte_first();
1234
1341
    blob_ptr_size= portable_sizeof_char_ptr;
1235
1342
 
1236
1343
    uint32_t field_length= 0; //Assignment is for compiler complaint.
1315
1422
    case DRIZZLE_TYPE_LONGLONG:
1316
1423
      field_length= MAX_BIGINT_WIDTH;
1317
1424
      break;
1318
 
    case DRIZZLE_TYPE_UUID:
1319
 
      field_length= field::Uuid::max_string_length();
1320
 
      break;
1321
1425
    case DRIZZLE_TYPE_NULL:
1322
1426
      abort(); // Programming error
1323
1427
    }
1324
1428
 
1325
 
    assert(enum_field_types_size == 12);
1326
 
 
1327
1429
    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());
 
1430
                                field_length,
 
1431
                                pfield.constraints().is_nullable(),
 
1432
                                null_pos,
 
1433
                                null_bit_pos,
 
1434
                                decimals,
 
1435
                                field_type,
 
1436
                                charset,
 
1437
                                (Field::utype) MTYP_TYPENR(unireg_type),
 
1438
                                ((field_type == DRIZZLE_TYPE_ENUM) ?
 
1439
                                 &intervals[interval_nr++]
 
1440
                                 : (TYPELIB*) 0),
 
1441
                                getTableProto()->field(fieldnr).name().c_str());
1338
1442
 
1339
1443
    field[fieldnr]= f;
1340
1444
 
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
1445
    // This needs to go, we should be setting the "use" on the field so that
1360
1446
    // it does not reference the share/table.
1361
 
    table::Shell temp_table(*this); /* Use this so that BLOB DEFAULT '' works */
 
1447
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
 
1448
    temp_table.setShare(this);
1362
1449
    temp_table.in_use= &session;
1363
1450
 
1364
1451
    f->init(&temp_table); /* blob default values need table obj */
1385
1472
        return local_error;
1386
1473
      }
1387
1474
    }
1388
 
    else if (f->real_type() == DRIZZLE_TYPE_ENUM && (f->flags & NOT_NULL_FLAG))
 
1475
    else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
 
1476
             (f->flags & NOT_NULL_FLAG))
1389
1477
    {
1390
1478
      f->set_notnull();
1391
1479
      f->store((int64_t) 1, true);
1399
1487
    f->setTable(NULL);
1400
1488
    f->orig_table= NULL;
1401
1489
 
1402
 
    f->setPosition(fieldnr);
 
1490
    f->field_index= fieldnr;
1403
1491
    f->comment= comment;
1404
1492
    if (! default_value &&
1405
1493
        ! (f->unireg_check==Field::NEXT_NUMBER) &&
1412
1500
    if (f->unireg_check == Field::NEXT_NUMBER)
1413
1501
      found_next_number_field= &(field[fieldnr]);
1414
1502
 
 
1503
    if (timestamp_field == f)
 
1504
      timestamp_field_offset= fieldnr;
 
1505
 
1415
1506
    if (use_hash) /* supposedly this never fails... but comments lie */
1416
1507
    {
1417
1508
      const char *local_field_name= field[fieldnr]->field_name;
1418
1509
      name_hash.insert(make_pair(local_field_name, &(field[fieldnr])));
1419
1510
    }
 
1511
 
1420
1512
  }
1421
1513
 
1422
1514
  keyinfo= key_info;
1441
1533
    We need to set the unused bits to 1. If the number of bits is a multiple
1442
1534
    of 8 there are no unused bits.
1443
1535
  */
 
1536
 
1444
1537
  if (null_count & 7)
1445
1538
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1446
1539
 
1617
1710
    }
1618
1711
  }
1619
1712
 
 
1713
  db_low_byte_first= true; // @todo Question this.
1620
1714
  all_set.clear();
1621
1715
  all_set.resize(fields);
1622
1716
  all_set.set();
1650
1744
 
1651
1745
  NOTES
1652
1746
  This function is called when the table definition is not cached in
1653
 
  definition::Cache::singleton().getCache()
 
1747
  table_def_cache
1654
1748
  The data is returned in 'share', which is alloced by
1655
1749
  alloc_table_share().. The code assumes that share is initialized.
1656
1750
 
1664
1758
  6    Unknown .frm version
1665
1759
*/
1666
1760
 
1667
 
int TableShare::open_table_def(Session& session, const TableIdentifier &identifier)
 
1761
int TableShare::open_table_def(Session& session, TableIdentifier &identifier)
1668
1762
{
1669
1763
  int local_error;
1670
1764
  bool error_given;
1672
1766
  local_error= 1;
1673
1767
  error_given= 0;
1674
1768
 
1675
 
  message::table::shared_ptr table;
 
1769
  message::Table table;
1676
1770
 
1677
1771
  local_error= plugin::StorageEngine::getTableDefinition(session, identifier, table);
1678
1772
 
1685
1779
    }
1686
1780
    else
1687
1781
    {
1688
 
      if (not table->IsInitialized())
 
1782
      if (not table.IsInitialized())
1689
1783
      {
1690
1784
        local_error= 4;
1691
1785
      }
1693
1787
    goto err_not_open;
1694
1788
  }
1695
1789
 
1696
 
  local_error= parse_table_proto(session, *table);
 
1790
  local_error= parse_table_proto(session, table);
1697
1791
 
1698
1792
  setTableCategory(TABLE_CATEGORY_USER);
1699
1793
 
1731
1825
  5    Error (see open_table_error: charset unavailable)
1732
1826
  7    Table definition has changed in engine
1733
1827
*/
 
1828
 
1734
1829
int TableShare::open_table_from_share(Session *session,
1735
1830
                                      const TableIdentifier &identifier,
1736
1831
                                      const char *alias,
1737
1832
                                      uint32_t db_stat, uint32_t ha_open_flags,
1738
1833
                                      Table &outparam)
1739
1834
{
 
1835
  int local_error;
 
1836
  uint32_t records;
1740
1837
  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
1838
  unsigned char *record= NULL;
1769
1839
  Field **field_ptr;
1770
1840
 
1774
1844
  local_error= 1;
1775
1845
  outparam.resetTable(session, this, db_stat);
1776
1846
 
1777
 
  outparam.setAlias(alias);
 
1847
  if (not (outparam.alias= strdup(alias)))
 
1848
    goto err;
1778
1849
 
1779
1850
  /* Allocate Cursor */
1780
 
  if (not (outparam.cursor= db_type()->getCursor(outparam)))
1781
 
    return local_error;
 
1851
  if (not (outparam.cursor= db_type()->getCursor(*this)))
 
1852
    goto err;
1782
1853
 
1783
1854
  local_error= 4;
1784
1855
  records= 0;
1788
1859
  records++;
1789
1860
 
1790
1861
  if (!(record= (unsigned char*) outparam.alloc_root(rec_buff_length * records)))
1791
 
    return local_error;
 
1862
    goto err;
1792
1863
 
1793
1864
  if (records == 0)
1794
1865
  {
1804
1875
      outparam.record[1]= outparam.getInsertRecord();   // Safety
1805
1876
  }
1806
1877
 
1807
 
#ifdef HAVE_VALGRIND
 
1878
#ifdef HAVE_purify
1808
1879
  /*
1809
1880
    We need this because when we read var-length rows, we are not updating
1810
1881
    bytes after end of varchar
1824
1895
 
1825
1896
  if (!(field_ptr = (Field **) outparam.alloc_root( (uint32_t) ((fields+1)* sizeof(Field*)))))
1826
1897
  {
1827
 
    return local_error;
 
1898
    goto err;
1828
1899
  }
1829
1900
 
1830
1901
  outparam.setFields(field_ptr);
1837
1908
  for (uint32_t i= 0 ; i < fields; i++, field_ptr++)
1838
1909
  {
1839
1910
    if (!((*field_ptr)= field[i]->clone(outparam.getMemRoot(), &outparam)))
1840
 
      return local_error;
 
1911
      goto err;
1841
1912
  }
1842
1913
  (*field_ptr)= 0;                              // End marker
1843
1914
 
1845
1916
    outparam.found_next_number_field=
1846
1917
      outparam.getField(positionFields(found_next_number_field));
1847
1918
  if (timestamp_field)
1848
 
    outparam.timestamp_field= (Field_timestamp*) outparam.getField(timestamp_field->position());
 
1919
    outparam.timestamp_field= (Field_timestamp*) outparam.getField(timestamp_field_offset);
 
1920
 
1849
1921
 
1850
1922
  /* Fix key->name and key_part->field */
1851
1923
  if (key_parts)
1855
1927
    uint32_t n_length;
1856
1928
    n_length= keys*sizeof(KeyInfo) + key_parts*sizeof(KeyPartInfo);
1857
1929
    if (!(local_key_info= (KeyInfo*) outparam.alloc_root(n_length)))
1858
 
      return local_error;
 
1930
      goto err;
1859
1931
    outparam.key_info= local_key_info;
1860
1932
    key_part= (reinterpret_cast<KeyPartInfo*> (local_key_info+keys));
1861
1933
 
1899
1971
  outparam.tmp_set.resize(fields);
1900
1972
  outparam.default_column_bitmaps();
1901
1973
 
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
1974
  /* The table struct is now initialized;  Open the table */
1911
 
  int local_error= 2;
 
1975
  local_error= 2;
1912
1976
  if (db_stat)
1913
1977
  {
1914
1978
    assert(!(db_stat & HA_WAIT_IF_LOCKED));
1915
1979
    int ha_err;
1916
1980
 
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))))
 
1981
    if ((ha_err= (outparam.cursor->ha_open(identifier, &outparam,
 
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))))
1920
1984
    {
1921
1985
      switch (ha_err)
1922
1986
      {
1943
2007
          local_error= 7;
1944
2008
        break;
1945
2009
      }
1946
 
      return local_error;
 
2010
      goto err;
1947
2011
    }
1948
2012
  }
1949
2013
 
1950
2014
  return 0;
 
2015
 
 
2016
err:
 
2017
  if (!error_reported)
 
2018
    open_table_error(local_error, errno, 0);
 
2019
 
 
2020
  delete outparam.cursor;
 
2021
  outparam.cursor= 0;                           // For easier error checking
 
2022
  outparam.db_stat= 0;
 
2023
  outparam.getMemRoot()->free_root(MYF(0));       // Safe to call on zeroed root
 
2024
  free((char*) outparam.alias);
 
2025
 
 
2026
  return (local_error);
1951
2027
}
1952
2028
 
1953
2029
/* error message when opening a form cursor */
2037
2113
  case DRIZZLE_TYPE_DATE:
2038
2114
  case DRIZZLE_TYPE_DATETIME:
2039
2115
  case DRIZZLE_TYPE_TIMESTAMP:
2040
 
  case DRIZZLE_TYPE_UUID:
2041
2116
    field_charset= &my_charset_bin;
2042
2117
  default: break;
2043
2118
  }
2055
2130
  case DRIZZLE_TYPE_VARCHAR:
2056
2131
    setVariableWidth();
2057
2132
    return new (&mem_root) Field_varstring(ptr,field_length,
2058
 
                                      ha_varchar_packlength(field_length),
 
2133
                                      HA_VARCHAR_PACKLENGTH(field_length),
2059
2134
                                      null_pos,null_bit,
2060
2135
                                      field_name,
2061
2136
                                      field_charset);
2065
2140
                                 null_bit,
2066
2141
                                 field_name,
2067
2142
                                 this,
 
2143
                                 calc_pack_length(DRIZZLE_TYPE_LONG, 0),
2068
2144
                                 field_charset);
2069
2145
  case DRIZZLE_TYPE_DECIMAL:
2070
2146
    return new (&mem_root) Field_decimal(ptr,
2086
2162
                                   decimals,
2087
2163
                                   false,
2088
2164
                                   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
2165
  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);
 
2166
    return new (&mem_root) Field_long(ptr,
 
2167
                                 field_length,
 
2168
                                 null_pos,
 
2169
                                 null_bit,
 
2170
                                 unireg_check,
 
2171
                                 field_name,
 
2172
                                 false,
 
2173
                                 false /* is_unsigned */);
2102
2174
  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);
 
2175
    return new (&mem_root) Field_int64_t(ptr,
 
2176
                                    field_length,
 
2177
                                    null_pos,
 
2178
                                    null_bit,
 
2179
                                    unireg_check,
 
2180
                                    field_name,
 
2181
                                    false,
 
2182
                                    false /* is_unsigned */);
2109
2183
  case DRIZZLE_TYPE_TIMESTAMP:
2110
2184
    return new (&mem_root) Field_timestamp(ptr,
2111
2185
                                      field_length,
2132
2206
                                 field_length,
2133
2207
                                 field_name,
2134
2208
                                 field_charset);
 
2209
  default: // Impossible (Wrong version)
 
2210
    break;
2135
2211
  }
2136
 
  assert(0);
2137
 
  abort();
 
2212
  return 0;
2138
2213
}
2139
2214
 
2140
2215