~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/definition/table.cc

  • Committer: Brian Aker
  • Date: 2008-12-23 07:19:26 UTC
  • Revision ID: brian@tangent.org-20081223071926-69z2ugpftfz1lfnm
Remove dead variables.

Show diffs side-by-side

added added

removed removed

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