~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2010-05-11 18:10:13 UTC
  • mto: This revision was merged to the branch mainline in revision 1528.
  • Revision ID: brian@gaz-20100511181013-ul0kh00zzk3j8k76
Move all TableShare methods into .cc file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
74
74
 
75
75
/*************************************************************************/
76
76
 
77
 
/* Get column name from column hash */
78
 
 
79
 
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
80
 
{
81
 
  *length= (uint32_t) strlen((*buff)->field_name);
82
 
  return (unsigned char*) (*buff)->field_name;
83
 
}
84
 
 
85
 
 
86
 
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
87
 
{
88
 
  enum_field_types field_type;
89
 
 
90
 
  switch(proto_field_type)
91
 
  {
92
 
  case message::Table::Field::INTEGER:
93
 
    field_type= DRIZZLE_TYPE_LONG;
94
 
    break;
95
 
  case message::Table::Field::DOUBLE:
96
 
    field_type= DRIZZLE_TYPE_DOUBLE;
97
 
    break;
98
 
  case message::Table::Field::TIMESTAMP:
99
 
    field_type= DRIZZLE_TYPE_TIMESTAMP;
100
 
    break;
101
 
  case message::Table::Field::BIGINT:
102
 
    field_type= DRIZZLE_TYPE_LONGLONG;
103
 
    break;
104
 
  case message::Table::Field::DATETIME:
105
 
    field_type= DRIZZLE_TYPE_DATETIME;
106
 
    break;
107
 
  case message::Table::Field::DATE:
108
 
    field_type= DRIZZLE_TYPE_DATE;
109
 
    break;
110
 
  case message::Table::Field::VARCHAR:
111
 
    field_type= DRIZZLE_TYPE_VARCHAR;
112
 
    break;
113
 
  case message::Table::Field::DECIMAL:
114
 
    field_type= DRIZZLE_TYPE_DECIMAL;
115
 
    break;
116
 
  case message::Table::Field::ENUM:
117
 
    field_type= DRIZZLE_TYPE_ENUM;
118
 
    break;
119
 
  case message::Table::Field::BLOB:
120
 
    field_type= DRIZZLE_TYPE_BLOB;
121
 
    break;
122
 
  default:
123
 
    field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
124
 
    assert(1);
125
 
  }
126
 
 
127
 
  return field_type;
128
 
}
129
 
 
130
 
static Item *default_value_item(enum_field_types field_type,
131
 
                                const CHARSET_INFO *charset,
132
 
                                bool default_null, const string *default_value,
133
 
                                const string *default_bin_value)
134
 
{
135
 
  Item *default_item= NULL;
136
 
  int error= 0;
137
 
 
138
 
  if (default_null)
139
 
  {
140
 
    return new Item_null();
141
 
  }
142
 
 
143
 
  switch(field_type)
144
 
  {
145
 
  case DRIZZLE_TYPE_LONG:
146
 
  case DRIZZLE_TYPE_LONGLONG:
147
 
    default_item= new Item_int(default_value->c_str(),
148
 
                               (int64_t) internal::my_strtoll10(default_value->c_str(),
149
 
                                                                NULL,
150
 
                                                                &error),
151
 
                               default_value->length());
152
 
    break;
153
 
  case DRIZZLE_TYPE_DOUBLE:
154
 
    default_item= new Item_float(default_value->c_str(),
155
 
                                 default_value->length());
156
 
    break;
157
 
  case DRIZZLE_TYPE_NULL:
158
 
    assert(false);
159
 
  case DRIZZLE_TYPE_TIMESTAMP:
160
 
  case DRIZZLE_TYPE_DATETIME:
161
 
  case DRIZZLE_TYPE_DATE:
162
 
    if (default_value->compare("NOW()") == 0)
163
 
      break;
164
 
  case DRIZZLE_TYPE_ENUM:
165
 
    default_item= new Item_string(default_value->c_str(),
166
 
                                  default_value->length(),
167
 
                                  system_charset_info);
168
 
    break;
169
 
  case DRIZZLE_TYPE_VARCHAR:
170
 
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
171
 
    if (charset==&my_charset_bin)
172
 
    {
173
 
      default_item= new Item_string(default_bin_value->c_str(),
174
 
                                    default_bin_value->length(),
175
 
                                    &my_charset_bin);
176
 
    }
177
 
    else
178
 
    {
179
 
      default_item= new Item_string(default_value->c_str(),
180
 
                                    default_value->length(),
181
 
                                    system_charset_info);
182
 
    }
183
 
    break;
184
 
  case DRIZZLE_TYPE_DECIMAL:
185
 
    default_item= new Item_decimal(default_value->c_str(),
186
 
                                   default_value->length(),
187
 
                                   system_charset_info);
188
 
    break;
189
 
  }
190
 
 
191
 
  return default_item;
192
 
}
193
 
 
194
 
int TableShare::inner_parse_table_proto(Session& session, message::Table &table)
195
 
{
196
 
  TableShare *share= this;
197
 
  int local_error= 0;
198
 
 
199
 
  if (! table.IsInitialized())
200
 
  {
201
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table.InitializationErrorString().c_str());
202
 
    return ER_CORRUPT_TABLE_DEFINITION;
203
 
  }
204
 
 
205
 
  share->setTableProto(new(nothrow) message::Table(table));
206
 
 
207
 
  share->storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
208
 
  assert(share->storage_engine); // We use an assert() here because we should never get this far and still have no suitable engine.
209
 
 
210
 
  message::Table::TableOptions table_options;
211
 
 
212
 
  if (table.has_options())
213
 
    table_options= table.options();
214
 
 
215
 
  uint32_t local_db_create_options= 0;
216
 
 
217
 
  if (table_options.pack_record())
218
 
    local_db_create_options|= HA_OPTION_PACK_RECORD;
219
 
 
220
 
  /* local_db_create_options was stored as 2 bytes in FRM
221
 
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
222
 
   */
223
 
  share->db_create_options= (local_db_create_options & 0x0000FFFF);
224
 
  share->db_options_in_use= share->db_create_options;
225
 
 
226
 
  share->row_type= table_options.has_row_type() ?
227
 
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
228
 
 
229
 
  share->block_size= table_options.has_block_size() ?
230
 
    table_options.block_size() : 0;
231
 
 
232
 
  share->table_charset= get_charset(table_options.has_collation_id()?
233
 
                                    table_options.collation_id() : 0);
234
 
 
235
 
  if (!share->table_charset)
236
 
  {
237
 
    /* unknown charset in head[38] or pre-3.23 frm */
238
 
    if (use_mb(default_charset_info))
239
 
    {
240
 
      /* Warn that we may be changing the size of character columns */
241
 
      errmsg_printf(ERRMSG_LVL_WARN,
242
 
                    _("'%s' had no or invalid character set, "
243
 
                      "and default character set is multi-byte, "
244
 
                      "so character column sizes may have changed"),
245
 
                    share->getPath());
246
 
    }
247
 
    share->table_charset= default_charset_info;
248
 
  }
249
 
 
250
 
  share->db_record_offset= 1;
251
 
 
252
 
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
253
 
 
254
 
  share->keys= table.indexes_size();
255
 
 
256
 
  share->key_parts= 0;
257
 
  for (int indx= 0; indx < table.indexes_size(); indx++)
258
 
    share->key_parts+= table.indexes(indx).index_part_size();
259
 
 
260
 
  share->key_info= (KEY*) share->alloc_root( table.indexes_size() * sizeof(KEY) +share->key_parts*sizeof(KEY_PART_INFO));
261
 
 
262
 
  KEY_PART_INFO *key_part;
263
 
 
264
 
  key_part= reinterpret_cast<KEY_PART_INFO*>
265
 
    (share->key_info+table.indexes_size());
266
 
 
267
 
 
268
 
  ulong *rec_per_key= (ulong*) share->alloc_root(sizeof(ulong*)*share->key_parts);
269
 
 
270
 
  share->keynames.count= table.indexes_size();
271
 
  share->keynames.name= NULL;
272
 
  share->keynames.type_names= (const char**)
273
 
    share->alloc_root(sizeof(char*) * (table.indexes_size()+1));
274
 
 
275
 
  share->keynames.type_lengths= (unsigned int*)
276
 
    share->alloc_root(sizeof(unsigned int) * (table.indexes_size()+1));
277
 
 
278
 
  share->keynames.type_names[share->keynames.count]= NULL;
279
 
  share->keynames.type_lengths[share->keynames.count]= 0;
280
 
 
281
 
  KEY* keyinfo= share->key_info;
282
 
  for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
283
 
  {
284
 
    message::Table::Index indx= table.indexes(keynr);
285
 
 
286
 
    keyinfo->table= 0;
287
 
    keyinfo->flags= 0;
288
 
 
289
 
    if (indx.is_unique())
290
 
      keyinfo->flags|= HA_NOSAME;
291
 
 
292
 
    if (indx.has_options())
293
 
    {
294
 
      message::Table::Index::IndexOptions indx_options= indx.options();
295
 
      if (indx_options.pack_key())
296
 
        keyinfo->flags|= HA_PACK_KEY;
297
 
 
298
 
      if (indx_options.var_length_key())
299
 
        keyinfo->flags|= HA_VAR_LENGTH_PART;
300
 
 
301
 
      if (indx_options.null_part_key())
302
 
        keyinfo->flags|= HA_NULL_PART_KEY;
303
 
 
304
 
      if (indx_options.binary_pack_key())
305
 
        keyinfo->flags|= HA_BINARY_PACK_KEY;
306
 
 
307
 
      if (indx_options.has_partial_segments())
308
 
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
309
 
 
310
 
      if (indx_options.auto_generated_key())
311
 
        keyinfo->flags|= HA_GENERATED_KEY;
312
 
 
313
 
      if (indx_options.has_key_block_size())
314
 
      {
315
 
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
316
 
        keyinfo->block_size= indx_options.key_block_size();
317
 
      }
318
 
      else
319
 
      {
320
 
        keyinfo->block_size= 0;
321
 
      }
322
 
    }
323
 
 
324
 
    switch (indx.type())
325
 
    {
326
 
    case message::Table::Index::UNKNOWN_INDEX:
327
 
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
328
 
      break;
329
 
    case message::Table::Index::BTREE:
330
 
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
331
 
      break;
332
 
    case message::Table::Index::HASH:
333
 
      keyinfo->algorithm= HA_KEY_ALG_HASH;
334
 
      break;
335
 
 
336
 
    default:
337
 
      /* TODO: suitable warning ? */
338
 
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
339
 
      break;
340
 
    }
341
 
 
342
 
    keyinfo->key_length= indx.key_length();
343
 
 
344
 
    keyinfo->key_parts= indx.index_part_size();
345
 
 
346
 
    keyinfo->key_part= key_part;
347
 
    keyinfo->rec_per_key= rec_per_key;
348
 
 
349
 
    for (unsigned int partnr= 0;
350
 
         partnr < keyinfo->key_parts;
351
 
         partnr++, key_part++)
352
 
    {
353
 
      message::Table::Index::IndexPart part;
354
 
      part= indx.index_part(partnr);
355
 
 
356
 
      *rec_per_key++= 0;
357
 
 
358
 
      key_part->field= NULL;
359
 
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
360
 
      key_part->null_bit= 0;
361
 
      /* key_part->null_offset is only set if null_bit (see later) */
362
 
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
363
 
      /* key_part->type ???? */
364
 
      key_part->key_part_flag= 0;
365
 
      if (part.has_in_reverse_order())
366
 
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
367
 
 
368
 
      key_part->length= part.compare_length();
369
 
 
370
 
      key_part->store_length= key_part->length;
371
 
 
372
 
      /* key_part->offset is set later */
373
 
      key_part->key_type= part.key_type();
374
 
    }
375
 
 
376
 
    if (! indx.has_comment())
377
 
    {
378
 
      keyinfo->comment.length= 0;
379
 
      keyinfo->comment.str= NULL;
380
 
    }
381
 
    else
382
 
    {
383
 
      keyinfo->flags|= HA_USES_COMMENT;
384
 
      keyinfo->comment.length= indx.comment().length();
385
 
      keyinfo->comment.str= share->strmake_root(indx.comment().c_str(), keyinfo->comment.length);
386
 
    }
387
 
 
388
 
    keyinfo->name= share->strmake_root(indx.name().c_str(), indx.name().length());
389
 
 
390
 
    share->keynames.type_names[keynr]= keyinfo->name;
391
 
    share->keynames.type_lengths[keynr]= indx.name().length();
392
 
  }
393
 
 
394
 
  share->keys_for_keyread.reset();
395
 
  set_prefix(share->keys_in_use, share->keys);
396
 
 
397
 
  share->fields= table.field_size();
398
 
 
399
 
  share->field= (Field**) share->alloc_root(((share->fields+1) * sizeof(Field*)));
400
 
  share->field[share->fields]= NULL;
401
 
 
402
 
  uint32_t local_null_fields= 0;
403
 
  share->reclength= 0;
404
 
 
405
 
  vector<uint32_t> field_offsets;
406
 
  vector<uint32_t> field_pack_length;
407
 
 
408
 
  field_offsets.resize(share->fields);
409
 
  field_pack_length.resize(share->fields);
410
 
 
411
 
  uint32_t interval_count= 0;
412
 
  uint32_t interval_parts= 0;
413
 
 
414
 
  uint32_t stored_columns_reclength= 0;
415
 
 
416
 
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
417
 
  {
418
 
    message::Table::Field pfield= table.field(fieldnr);
419
 
    if (pfield.constraints().is_nullable())
420
 
      local_null_fields++;
421
 
 
422
 
    enum_field_types drizzle_field_type=
423
 
      proto_field_type_to_drizzle_type(pfield.type());
424
 
 
425
 
    field_offsets[fieldnr]= stored_columns_reclength;
426
 
 
427
 
    /* the below switch is very similar to
428
 
       CreateField::create_length_to_internal_length in field.cc
429
 
       (which should one day be replace by just this code)
430
 
    */
431
 
    switch(drizzle_field_type)
432
 
    {
433
 
    case DRIZZLE_TYPE_BLOB:
434
 
    case DRIZZLE_TYPE_VARCHAR:
435
 
      {
436
 
        message::Table::Field::StringFieldOptions field_options= pfield.string_options();
437
 
 
438
 
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id() ?
439
 
                                            field_options.collation_id() : 0);
440
 
 
441
 
        if (! cs)
442
 
          cs= default_charset_info;
443
 
 
444
 
        field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type,
445
 
                                                     field_options.length() * cs->mbmaxlen);
446
 
      }
447
 
      break;
448
 
    case DRIZZLE_TYPE_ENUM:
449
 
      {
450
 
        message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
451
 
 
452
 
        field_pack_length[fieldnr]=
453
 
          get_enum_pack_length(field_options.field_value_size());
454
 
 
455
 
        interval_count++;
456
 
        interval_parts+= field_options.field_value_size();
457
 
      }
458
 
      break;
459
 
    case DRIZZLE_TYPE_DECIMAL:
460
 
      {
461
 
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
462
 
 
463
 
        field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
464
 
      }
465
 
      break;
466
 
    default:
467
 
      /* Zero is okay here as length is fixed for other types. */
468
 
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
469
 
    }
470
 
 
471
 
    share->reclength+= field_pack_length[fieldnr];
472
 
    stored_columns_reclength+= field_pack_length[fieldnr];
473
 
  }
474
 
 
475
 
  /* data_offset added to stored_rec_length later */
476
 
  share->stored_rec_length= stored_columns_reclength;
477
 
 
478
 
  share->null_fields= local_null_fields;
479
 
 
480
 
  ulong null_bits= local_null_fields;
481
 
  if (! table_options.pack_record())
482
 
    null_bits++;
483
 
  ulong data_offset= (null_bits + 7)/8;
484
 
 
485
 
 
486
 
  share->reclength+= data_offset;
487
 
  share->stored_rec_length+= data_offset;
488
 
 
489
 
  ulong local_rec_buff_length;
490
 
 
491
 
  local_rec_buff_length= ALIGN_SIZE(share->reclength + 1);
492
 
  share->rec_buff_length= local_rec_buff_length;
493
 
 
494
 
  unsigned char* record= NULL;
495
 
 
496
 
  if (! (record= (unsigned char *) share->alloc_root(local_rec_buff_length)))
497
 
    abort();
498
 
 
499
 
  memset(record, 0, local_rec_buff_length);
500
 
 
501
 
  int null_count= 0;
502
 
 
503
 
  if (! table_options.pack_record())
504
 
  {
505
 
    null_count++; // one bit for delete mark.
506
 
    *record|= 1;
507
 
  }
508
 
 
509
 
  share->default_values= record;
510
 
 
511
 
  if (interval_count)
512
 
  {
513
 
    share->intervals= (TYPELIB *) share->alloc_root(interval_count*sizeof(TYPELIB));
514
 
  }
515
 
  else
516
 
  {
517
 
    share->intervals= NULL;
518
 
  }
519
 
 
520
 
  share->fieldnames.type_names= (const char **) share->alloc_root((share->fields + 1) * sizeof(char*));
521
 
 
522
 
  share->fieldnames.type_lengths= (unsigned int *) share->alloc_root((share->fields + 1) * sizeof(unsigned int));
523
 
 
524
 
  share->fieldnames.type_names[share->fields]= NULL;
525
 
  share->fieldnames.type_lengths[share->fields]= 0;
526
 
  share->fieldnames.count= share->fields;
527
 
 
528
 
 
529
 
  /* Now fix the TYPELIBs for the intervals (enum values)
530
 
     and field names.
531
 
   */
532
 
 
533
 
  uint32_t interval_nr= 0;
534
 
 
535
 
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
536
 
  {
537
 
    message::Table::Field pfield= table.field(fieldnr);
538
 
 
539
 
    /* field names */
540
 
    share->fieldnames.type_names[fieldnr]= share->strmake_root(pfield.name().c_str(), pfield.name().length());
541
 
 
542
 
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
543
 
 
544
 
    /* enum typelibs */
545
 
    if (pfield.type() != message::Table::Field::ENUM)
546
 
      continue;
547
 
 
548
 
    message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
549
 
 
550
 
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id() ?
551
 
                                             field_options.collation_id() : 0);
552
 
 
553
 
    if (! charset)
554
 
      charset= default_charset_info;
555
 
 
556
 
    TYPELIB *t= &(share->intervals[interval_nr]);
557
 
 
558
 
    t->type_names= (const char**)share->alloc_root((field_options.field_value_size() + 1) * sizeof(char*));
559
 
 
560
 
    t->type_lengths= (unsigned int*) share->alloc_root((field_options.field_value_size() + 1) * sizeof(unsigned int));
561
 
 
562
 
    t->type_names[field_options.field_value_size()]= NULL;
563
 
    t->type_lengths[field_options.field_value_size()]= 0;
564
 
 
565
 
    t->count= field_options.field_value_size();
566
 
    t->name= NULL;
567
 
 
568
 
    for (int n= 0; n < field_options.field_value_size(); n++)
569
 
    {
570
 
      t->type_names[n]= share->strmake_root(field_options.field_value(n).c_str(), field_options.field_value(n).length());
571
 
 
572
 
      /* 
573
 
       * Go ask the charset what the length is as for "" length=1
574
 
       * and there's stripping spaces or some other crack going on.
575
 
       */
576
 
      uint32_t lengthsp;
577
 
      lengthsp= charset->cset->lengthsp(charset,
578
 
                                        t->type_names[n],
579
 
                                        field_options.field_value(n).length());
580
 
      t->type_lengths[n]= lengthsp;
581
 
    }
582
 
    interval_nr++;
583
 
  }
584
 
 
585
 
 
586
 
  /* and read the fields */
587
 
  interval_nr= 0;
588
 
 
589
 
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
590
 
 
591
 
  if (use_hash)
592
 
    use_hash= ! hash_init(&share->name_hash,
593
 
                          system_charset_info,
594
 
                          share->fields,
595
 
                          0,
596
 
                          0,
597
 
                          (hash_get_key) get_field_name,
598
 
                          0,
599
 
                          0);
600
 
 
601
 
  unsigned char* null_pos= record;;
602
 
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
603
 
 
604
 
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
605
 
  {
606
 
    message::Table::Field pfield= table.field(fieldnr);
607
 
 
608
 
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
609
 
 
610
 
    switch (pfield.format())
611
 
    {
612
 
    case message::Table::Field::DefaultFormat:
613
 
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
614
 
      break;
615
 
    case message::Table::Field::FixedFormat:
616
 
      column_format= COLUMN_FORMAT_TYPE_FIXED;
617
 
      break;
618
 
    case message::Table::Field::DynamicFormat:
619
 
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
620
 
      break;
621
 
    default:
622
 
      assert(1);
623
 
    }
624
 
 
625
 
    Field::utype unireg_type= Field::NONE;
626
 
 
627
 
    if (pfield.has_numeric_options() &&
628
 
        pfield.numeric_options().is_autoincrement())
629
 
    {
630
 
      unireg_type= Field::NEXT_NUMBER;
631
 
    }
632
 
 
633
 
    if (pfield.has_options() &&
634
 
        pfield.options().has_default_value() &&
635
 
        pfield.options().default_value().compare("NOW()") == 0)
636
 
    {
637
 
      if (pfield.options().has_update_value() &&
638
 
          pfield.options().update_value().compare("NOW()") == 0)
639
 
      {
640
 
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
641
 
      }
642
 
      else if (! pfield.options().has_update_value())
643
 
      {
644
 
        unireg_type= Field::TIMESTAMP_DN_FIELD;
645
 
      }
646
 
      else
647
 
        assert(1); // Invalid update value.
648
 
    }
649
 
    else if (pfield.has_options() &&
650
 
             pfield.options().has_update_value() &&
651
 
             pfield.options().update_value().compare("NOW()") == 0)
652
 
    {
653
 
      unireg_type= Field::TIMESTAMP_UN_FIELD;
654
 
    }
655
 
 
656
 
    LEX_STRING comment;
657
 
    if (!pfield.has_comment())
658
 
    {
659
 
      comment.str= (char*)"";
660
 
      comment.length= 0;
661
 
    }
662
 
    else
663
 
    {
664
 
      size_t len= pfield.comment().length();
665
 
      const char* str= pfield.comment().c_str();
666
 
 
667
 
      comment.str= share->strmake_root(str, len);
668
 
      comment.length= len;
669
 
    }
670
 
 
671
 
    enum_field_types field_type;
672
 
 
673
 
    field_type= proto_field_type_to_drizzle_type(pfield.type());
674
 
 
675
 
    const CHARSET_INFO *charset= &my_charset_bin;
676
 
 
677
 
    if (field_type == DRIZZLE_TYPE_BLOB ||
678
 
        field_type == DRIZZLE_TYPE_VARCHAR)
679
 
    {
680
 
      message::Table::Field::StringFieldOptions field_options= pfield.string_options();
681
 
 
682
 
      charset= get_charset(field_options.has_collation_id() ?
683
 
                           field_options.collation_id() : 0);
684
 
 
685
 
      if (! charset)
686
 
        charset= default_charset_info;
687
 
    }
688
 
 
689
 
    if (field_type == DRIZZLE_TYPE_ENUM)
690
 
    {
691
 
      message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
692
 
 
693
 
      charset= get_charset(field_options.has_collation_id()?
694
 
                           field_options.collation_id() : 0);
695
 
 
696
 
      if (! charset)
697
 
              charset= default_charset_info;
698
 
    }
699
 
 
700
 
    uint8_t decimals= 0;
701
 
    if (field_type == DRIZZLE_TYPE_DECIMAL
702
 
        || field_type == DRIZZLE_TYPE_DOUBLE)
703
 
    {
704
 
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
705
 
 
706
 
      if (! pfield.has_numeric_options() || ! fo.has_scale())
707
 
      {
708
 
        /*
709
 
          We don't write the default to table proto so
710
 
          if no decimals specified for DOUBLE, we use the default.
711
 
        */
712
 
        decimals= NOT_FIXED_DEC;
713
 
      }
714
 
      else
715
 
      {
716
 
        if (fo.scale() > DECIMAL_MAX_SCALE)
717
 
        {
718
 
          local_error= 4;
719
 
 
720
 
          return local_error;
721
 
        }
722
 
        decimals= static_cast<uint8_t>(fo.scale());
723
 
      }
724
 
    }
725
 
 
726
 
    Item *default_value= NULL;
727
 
 
728
 
    if (pfield.options().has_default_value() ||
729
 
        pfield.options().has_default_null()  ||
730
 
        pfield.options().has_default_bin_value())
731
 
    {
732
 
      default_value= default_value_item(field_type,
733
 
                                        charset,
734
 
                                        pfield.options().default_null(),
735
 
                                        &pfield.options().default_value(),
736
 
                                        &pfield.options().default_bin_value());
737
 
    }
738
 
 
739
 
 
740
 
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
741
 
    memset(&temp_table, 0, sizeof(temp_table));
742
 
    temp_table.s= share;
743
 
    temp_table.in_use= &session;
744
 
    temp_table.s->db_low_byte_first= true; //Cursor->low_byte_first();
745
 
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
746
 
 
747
 
    uint32_t field_length= 0; //Assignment is for compiler complaint.
748
 
 
749
 
    switch (field_type)
750
 
    {
751
 
    case DRIZZLE_TYPE_BLOB:
752
 
    case DRIZZLE_TYPE_VARCHAR:
753
 
    {
754
 
      message::Table::Field::StringFieldOptions field_options= pfield.string_options();
755
 
 
756
 
      charset= get_charset(field_options.has_collation_id() ?
757
 
                           field_options.collation_id() : 0);
758
 
 
759
 
      if (! charset)
760
 
        charset= default_charset_info;
761
 
 
762
 
      field_length= field_options.length() * charset->mbmaxlen;
763
 
    }
764
 
      break;
765
 
    case DRIZZLE_TYPE_DOUBLE:
766
 
    {
767
 
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
768
 
      if (!fo.has_precision() && !fo.has_scale())
769
 
      {
770
 
        field_length= DBL_DIG+7;
771
 
      }
772
 
      else
773
 
      {
774
 
        field_length= fo.precision();
775
 
      }
776
 
      if (field_length < decimals &&
777
 
          decimals != NOT_FIXED_DEC)
778
 
      {
779
 
        my_error(ER_M_BIGGER_THAN_D, MYF(0), pfield.name().c_str());
780
 
        local_error= 1;
781
 
 
782
 
        return local_error;
783
 
      }
784
 
      break;
785
 
    }
786
 
    case DRIZZLE_TYPE_DECIMAL:
787
 
    {
788
 
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
789
 
 
790
 
      field_length= my_decimal_precision_to_length(fo.precision(), fo.scale(),
791
 
                                                   false);
792
 
      break;
793
 
    }
794
 
    case DRIZZLE_TYPE_TIMESTAMP:
795
 
    case DRIZZLE_TYPE_DATETIME:
796
 
      field_length= DateTime::MAX_STRING_LENGTH;
797
 
      break;
798
 
    case DRIZZLE_TYPE_DATE:
799
 
      field_length= Date::MAX_STRING_LENGTH;
800
 
      break;
801
 
    case DRIZZLE_TYPE_ENUM:
802
 
    {
803
 
      field_length= 0;
804
 
 
805
 
      message::Table::Field::EnumerationValues fo= pfield.enumeration_values();
806
 
 
807
 
      for (int valnr= 0; valnr < fo.field_value_size(); valnr++)
808
 
      {
809
 
        if (fo.field_value(valnr).length() > field_length)
810
 
        {
811
 
          field_length= charset->cset->numchars(charset,
812
 
                                                fo.field_value(valnr).c_str(),
813
 
                                                fo.field_value(valnr).c_str()
814
 
                                                + fo.field_value(valnr).length())
815
 
            * charset->mbmaxlen;
816
 
        }
817
 
      }
818
 
    }
819
 
    break;
820
 
    case DRIZZLE_TYPE_LONG:
821
 
      {
822
 
        uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
823
 
          field_length= MAX_INT_WIDTH+sign_len;
824
 
      }
825
 
      break;
826
 
    case DRIZZLE_TYPE_LONGLONG:
827
 
      field_length= MAX_BIGINT_WIDTH;
828
 
      break;
829
 
    case DRIZZLE_TYPE_NULL:
830
 
      abort(); // Programming error
831
 
    }
832
 
 
833
 
    Field* f= share->make_field(record + field_offsets[fieldnr] + data_offset,
834
 
                                field_length,
835
 
                                pfield.constraints().is_nullable(),
836
 
                                null_pos,
837
 
                                null_bit_pos,
838
 
                                decimals,
839
 
                                field_type,
840
 
                                charset,
841
 
                                (Field::utype) MTYP_TYPENR(unireg_type),
842
 
                                ((field_type == DRIZZLE_TYPE_ENUM) ?
843
 
                                 share->intervals + (interval_nr++)
844
 
                                 : (TYPELIB*) 0),
845
 
                                share->fieldnames.type_names[fieldnr]);
846
 
 
847
 
    share->field[fieldnr]= f;
848
 
 
849
 
    f->init(&temp_table); /* blob default values need table obj */
850
 
 
851
 
    if (! (f->flags & NOT_NULL_FLAG))
852
 
    {
853
 
      *f->null_ptr|= f->null_bit;
854
 
      if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
855
 
        null_pos++;
856
 
      null_count++;
857
 
    }
858
 
 
859
 
    if (default_value)
860
 
    {
861
 
      enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
862
 
      session.count_cuted_fields= CHECK_FIELD_WARN;
863
 
      int res= default_value->save_in_field(f, 1);
864
 
      session.count_cuted_fields= old_count_cuted_fields;
865
 
      if (res != 0 && res != 3) /* @TODO Huh? */
866
 
      {
867
 
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
868
 
        local_error= 1;
869
 
 
870
 
        return local_error;
871
 
      }
872
 
    }
873
 
    else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
874
 
             (f->flags & NOT_NULL_FLAG))
875
 
    {
876
 
      f->set_notnull();
877
 
      f->store((int64_t) 1, true);
878
 
    }
879
 
    else
880
 
    {
881
 
      f->reset();
882
 
    }
883
 
 
884
 
    /* hack to undo f->init() */
885
 
    f->table= NULL;
886
 
    f->orig_table= NULL;
887
 
 
888
 
    f->field_index= fieldnr;
889
 
    f->comment= comment;
890
 
    if (! default_value &&
891
 
        ! (f->unireg_check==Field::NEXT_NUMBER) &&
892
 
        (f->flags & NOT_NULL_FLAG) &&
893
 
        (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
894
 
    {
895
 
      f->flags|= NO_DEFAULT_VALUE_FLAG;
896
 
    }
897
 
 
898
 
    if (f->unireg_check == Field::NEXT_NUMBER)
899
 
      share->found_next_number_field= &(share->field[fieldnr]);
900
 
 
901
 
    if (share->timestamp_field == f)
902
 
      share->timestamp_field_offset= fieldnr;
903
 
 
904
 
    if (use_hash) /* supposedly this never fails... but comments lie */
905
 
      (void) my_hash_insert(&share->name_hash,
906
 
                            (unsigned char*)&(share->field[fieldnr]));
907
 
 
908
 
  }
909
 
 
910
 
  keyinfo= share->key_info;
911
 
  for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
912
 
  {
913
 
    key_part= keyinfo->key_part;
914
 
 
915
 
    for (unsigned int partnr= 0;
916
 
         partnr < keyinfo->key_parts;
917
 
         partnr++, key_part++)
918
 
    {
919
 
      /* 
920
 
       * Fix up key_part->offset by adding data_offset.
921
 
       * We really should compute offset as well.
922
 
       * But at least this way we are a little better.
923
 
       */
924
 
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
925
 
    }
926
 
  }
927
 
 
928
 
  /*
929
 
    We need to set the unused bits to 1. If the number of bits is a multiple
930
 
    of 8 there are no unused bits.
931
 
  */
932
 
 
933
 
  if (null_count & 7)
934
 
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
935
 
 
936
 
  share->null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
937
 
 
938
 
  share->last_null_bit_pos= null_bit_pos;
939
 
 
940
 
  /* Fix key stuff */
941
 
  if (share->key_parts)
942
 
  {
943
 
    uint32_t local_primary_key= (uint32_t) (find_type((char*) "PRIMARY",
944
 
                                                &share->keynames, 3) - 1); /* @TODO Huh? */
945
 
 
946
 
    keyinfo= share->key_info;
947
 
    key_part= keyinfo->key_part;
948
 
 
949
 
    for (uint32_t key= 0; key < share->keys; key++,keyinfo++)
950
 
    {
951
 
      uint32_t usable_parts= 0;
952
 
 
953
 
      if (local_primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
954
 
      {
955
 
        /*
956
 
          If the UNIQUE key doesn't have NULL columns and is not a part key
957
 
          declare this as a primary key.
958
 
        */
959
 
        local_primary_key=key;
960
 
        for (uint32_t i= 0; i < keyinfo->key_parts; i++)
961
 
        {
962
 
          uint32_t fieldnr= key_part[i].fieldnr;
963
 
          if (! fieldnr ||
964
 
              share->field[fieldnr-1]->null_ptr ||
965
 
              share->field[fieldnr-1]->key_length() != key_part[i].length)
966
 
          {
967
 
            local_primary_key= MAX_KEY; // Can't be used
968
 
            break;
969
 
          }
970
 
        }
971
 
      }
972
 
 
973
 
      for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
974
 
      {
975
 
        Field *local_field;
976
 
        if (! key_part->fieldnr)
977
 
        {
978
 
          return ENOMEM;
979
 
        }
980
 
        local_field= key_part->field= share->field[key_part->fieldnr-1];
981
 
        key_part->type= local_field->key_type();
982
 
        if (local_field->null_ptr)
983
 
        {
984
 
          key_part->null_offset=(uint32_t) ((unsigned char*) local_field->null_ptr - share->default_values);
985
 
          key_part->null_bit= local_field->null_bit;
986
 
          key_part->store_length+=HA_KEY_NULL_LENGTH;
987
 
          keyinfo->flags|=HA_NULL_PART_KEY;
988
 
          keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
989
 
          keyinfo->key_length+= HA_KEY_NULL_LENGTH;
990
 
        }
991
 
        if (local_field->type() == DRIZZLE_TYPE_BLOB ||
992
 
            local_field->real_type() == DRIZZLE_TYPE_VARCHAR)
993
 
        {
994
 
          if (local_field->type() == DRIZZLE_TYPE_BLOB)
995
 
            key_part->key_part_flag|= HA_BLOB_PART;
996
 
          else
997
 
            key_part->key_part_flag|= HA_VAR_LENGTH_PART;
998
 
          keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
999
 
          key_part->store_length+=HA_KEY_BLOB_LENGTH;
1000
 
          keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1001
 
        }
1002
 
        if (i == 0 && key != local_primary_key)
1003
 
          local_field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1004
 
                            (keyinfo->key_parts == 1)) ?
1005
 
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1006
 
        if (i == 0)
1007
 
          local_field->key_start.set(key);
1008
 
        if (local_field->key_length() == key_part->length &&
1009
 
            !(local_field->flags & BLOB_FLAG))
1010
 
        {
1011
 
          enum ha_key_alg algo= share->key_info[key].algorithm;
1012
 
          if (share->db_type()->index_flags(algo) & HA_KEYREAD_ONLY)
1013
 
          {
1014
 
            share->keys_for_keyread.set(key);
1015
 
            local_field->part_of_key.set(key);
1016
 
            local_field->part_of_key_not_clustered.set(key);
1017
 
          }
1018
 
          if (share->db_type()->index_flags(algo) & HA_READ_ORDER)
1019
 
            local_field->part_of_sortkey.set(key);
1020
 
        }
1021
 
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1022
 
            usable_parts == i)
1023
 
          usable_parts++;                       // For FILESORT
1024
 
        local_field->flags|= PART_KEY_FLAG;
1025
 
        if (key == local_primary_key)
1026
 
        {
1027
 
          local_field->flags|= PRI_KEY_FLAG;
1028
 
          /*
1029
 
            If this field is part of the primary key and all keys contains
1030
 
            the primary key, then we can use any key to find this column
1031
 
          */
1032
 
          if (share->storage_engine->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX))
1033
 
          {
1034
 
            local_field->part_of_key= share->keys_in_use;
1035
 
            if (local_field->part_of_sortkey.test(key))
1036
 
              local_field->part_of_sortkey= share->keys_in_use;
1037
 
          }
1038
 
        }
1039
 
        if (local_field->key_length() != key_part->length)
1040
 
        {
1041
 
          key_part->key_part_flag|= HA_PART_KEY_SEG;
1042
 
        }
1043
 
      }
1044
 
      keyinfo->usable_key_parts= usable_parts; // Filesort
1045
 
 
1046
 
      set_if_bigger(share->max_key_length,keyinfo->key_length+
1047
 
                    keyinfo->key_parts);
1048
 
      share->total_key_length+= keyinfo->key_length;
1049
 
 
1050
 
      if (keyinfo->flags & HA_NOSAME)
1051
 
      {
1052
 
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
1053
 
      }
1054
 
    }
1055
 
    if (local_primary_key < MAX_KEY &&
1056
 
        (share->keys_in_use.test(local_primary_key)))
1057
 
    {
1058
 
      share->primary_key= local_primary_key;
1059
 
      /*
1060
 
        If we are using an integer as the primary key then allow the user to
1061
 
        refer to it as '_rowid'
1062
 
      */
1063
 
      if (share->key_info[local_primary_key].key_parts == 1)
1064
 
      {
1065
 
        Field *local_field= share->key_info[local_primary_key].key_part[0].field;
1066
 
        if (local_field && local_field->result_type() == INT_RESULT)
1067
 
        {
1068
 
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
1069
 
          share->rowid_field_offset= (share->key_info[local_primary_key].key_part[0].
1070
 
                                      fieldnr);
1071
 
        }
1072
 
      }
1073
 
    }
1074
 
    else
1075
 
    {
1076
 
      share->primary_key = MAX_KEY; // we do not have a primary key
1077
 
    }
1078
 
  }
1079
 
  else
1080
 
  {
1081
 
    share->primary_key= MAX_KEY;
1082
 
  }
1083
 
 
1084
 
  if (share->found_next_number_field)
1085
 
  {
1086
 
    Field *reg_field= *share->found_next_number_field;
1087
 
    if ((int) (share->next_number_index= (uint32_t)
1088
 
               find_ref_key(share->key_info, share->keys,
1089
 
                            share->default_values, reg_field,
1090
 
                            &share->next_number_key_offset,
1091
 
                            &share->next_number_keypart)) < 0)
1092
 
    {
1093
 
      /* Wrong field definition */
1094
 
      local_error= 4;
1095
 
 
1096
 
      return local_error;
1097
 
    }
1098
 
    else
1099
 
    {
1100
 
      reg_field->flags |= AUTO_INCREMENT_FLAG;
1101
 
    }
1102
 
  }
1103
 
 
1104
 
  if (share->blob_fields)
1105
 
  {
1106
 
    Field **ptr;
1107
 
    uint32_t k, *save;
1108
 
 
1109
 
    /* Store offsets to blob fields to find them fast */
1110
 
    if (!(share->blob_field= save=
1111
 
          (uint*) share->alloc_root((uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1112
 
    {
1113
 
      return local_error;
1114
 
    }
1115
 
    for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
1116
 
    {
1117
 
      if ((*ptr)->flags & BLOB_FLAG)
1118
 
        (*save++)= k;
1119
 
    }
1120
 
  }
1121
 
 
1122
 
  share->db_low_byte_first= true; // @todo Question this.
1123
 
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1124
 
 
1125
 
  my_bitmap_map *bitmaps;
1126
 
 
1127
 
  if (!(bitmaps= (my_bitmap_map*) share->alloc_root(share->column_bitmap_size)))
1128
 
  { }
1129
 
  else
1130
 
  {
1131
 
    share->all_set.init(bitmaps, share->fields);
1132
 
    share->all_set.setAll();
1133
 
 
1134
 
    return (0);
1135
 
  }
1136
 
 
1137
 
  return local_error;
1138
 
}
1139
 
 
1140
 
int TableShare::parse_table_proto(Session& session, message::Table &table)
1141
 
{
1142
 
  int local_error= inner_parse_table_proto(session, table);
1143
 
 
1144
 
  if (not local_error)
1145
 
    return 0;
1146
 
 
1147
 
  error= local_error;
1148
 
  open_errno= errno;
1149
 
  errarg= 0;
1150
 
  hash_free(&name_hash);
1151
 
  open_table_error(local_error, open_errno, 0);
1152
 
 
1153
 
  return local_error;
1154
 
}
1155
 
 
1156
 
 
1157
 
/*
1158
 
  Read table definition from a binary / text based .frm cursor
1159
 
 
1160
 
  SYNOPSIS
1161
 
  open_table_def()
1162
 
  session               Thread Cursor
1163
 
  share         Fill this with table definition
1164
 
 
1165
 
  NOTES
1166
 
    This function is called when the table definition is not cached in
1167
 
    table_def_cache
1168
 
    The data is returned in 'share', which is alloced by
1169
 
    alloc_table_share().. The code assumes that share is initialized.
1170
 
 
1171
 
  RETURN VALUES
1172
 
   0    ok
1173
 
   1    Error (see open_table_error)
1174
 
   2    Error (see open_table_error)
1175
 
   3    Wrong data in .frm cursor
1176
 
   4    Error (see open_table_error)
1177
 
   5    Error (see open_table_error: charset unavailable)
1178
 
   6    Unknown .frm version
1179
 
*/
1180
 
 
1181
 
int TableShare::open_table_def(Session& session, TableIdentifier &identifier)
1182
 
{
1183
 
  int local_error;
1184
 
  bool error_given;
1185
 
 
1186
 
  local_error= 1;
1187
 
  error_given= 0;
1188
 
 
1189
 
  message::Table table;
1190
 
 
1191
 
  local_error= plugin::StorageEngine::getTableDefinition(session, identifier, table);
1192
 
 
1193
 
  if (local_error != EEXIST)
1194
 
  {
1195
 
    if (local_error > 0)
1196
 
    {
1197
 
      errno= local_error;
1198
 
      local_error= 1;
1199
 
    }
1200
 
    else
1201
 
    {
1202
 
      if (not table.IsInitialized())
1203
 
      {
1204
 
        local_error= 4;
1205
 
      }
1206
 
    }
1207
 
    goto err_not_open;
1208
 
  }
1209
 
 
1210
 
  local_error= parse_table_proto(session, table);
1211
 
 
1212
 
  setTableCategory(TABLE_CATEGORY_USER);
1213
 
 
1214
 
err_not_open:
1215
 
  if (local_error && !error_given)
1216
 
  {
1217
 
    error= local_error;
1218
 
    open_table_error(error, (open_errno= errno), 0);
1219
 
  }
1220
 
 
1221
 
  return(error);
1222
 
}
1223
 
 
1224
 
 
1225
 
/*
1226
 
  Open a table based on a TableShare
1227
 
 
1228
 
  SYNOPSIS
1229
 
    open_table_from_share()
1230
 
    session                     Thread Cursor
1231
 
    share               Table definition
1232
 
    alias               Alias for table
1233
 
    db_stat             open flags (for example HA_OPEN_KEYFILE|
1234
 
                        HA_OPEN_RNDFILE..) can be 0 (example in
1235
 
                        ha_example_table)
1236
 
    ha_open_flags       HA_OPEN_ABORT_IF_LOCKED etc..
1237
 
    outparam            result table
1238
 
 
1239
 
  RETURN VALUES
1240
 
   0    ok
1241
 
   1    Error (see open_table_error)
1242
 
   2    Error (see open_table_error)
1243
 
   3    Wrong data in .frm cursor
1244
 
   4    Error (see open_table_error)
1245
 
   5    Error (see open_table_error: charset unavailable)
1246
 
   7    Table definition has changed in engine
1247
 
*/
1248
 
 
1249
 
int TableShare::open_table_from_share(Session *session, const char *alias,
1250
 
                                      uint32_t db_stat, uint32_t ha_open_flags,
1251
 
                                      Table &outparam)
1252
 
{
1253
 
  int local_error;
1254
 
  uint32_t records, bitmap_size;
1255
 
  bool error_reported= false;
1256
 
  unsigned char *record, *bitmaps;
1257
 
  Field **field_ptr;
1258
 
 
1259
 
  /* Parsing of partitioning information from .frm needs session->lex set up. */
1260
 
  assert(session->lex->is_lex_started);
1261
 
 
1262
 
  local_error= 1;
1263
 
  outparam.resetTable(session, this, db_stat);
1264
 
 
1265
 
 
1266
 
  if (not (outparam.alias= strdup(alias)))
1267
 
    goto err;
1268
 
 
1269
 
  /* Allocate Cursor */
1270
 
  if (not (outparam.cursor= db_type()->getCursor(*this, &outparam.mem_root)))
1271
 
    goto err;
1272
 
 
1273
 
  local_error= 4;
1274
 
  records= 0;
1275
 
  if ((db_stat & HA_OPEN_KEYFILE))
1276
 
    records=1;
1277
 
 
1278
 
  records++;
1279
 
 
1280
 
  if (!(record= (unsigned char*) outparam.mem_root.alloc_root(rec_buff_length * records)))
1281
 
    goto err;
1282
 
 
1283
 
  if (records == 0)
1284
 
  {
1285
 
    /* We are probably in hard repair, and the buffers should not be used */
1286
 
    outparam.record[0]= outparam.record[1]= default_values;
1287
 
  }
1288
 
  else
1289
 
  {
1290
 
    outparam.record[0]= record;
1291
 
    if (records > 1)
1292
 
      outparam.record[1]= record+ rec_buff_length;
1293
 
    else
1294
 
      outparam.record[1]= outparam.record[0];   // Safety
1295
 
  }
1296
 
 
1297
 
#ifdef HAVE_purify
1298
 
  /*
1299
 
    We need this because when we read var-length rows, we are not updating
1300
 
    bytes after end of varchar
1301
 
  */
1302
 
  if (records > 1)
1303
 
  {
1304
 
    memcpy(outparam.record[0], default_values, rec_buff_length);
1305
 
    memcpy(outparam.record[1], default_values, null_bytes);
1306
 
    if (records > 2)
1307
 
      memcpy(outparam.record[1], default_values, rec_buff_length);
1308
 
  }
1309
 
#endif
1310
 
  if (records > 1)
1311
 
  {
1312
 
    memcpy(outparam.record[1], default_values, null_bytes);
1313
 
  }
1314
 
 
1315
 
  if (!(field_ptr = (Field **) outparam.mem_root.alloc_root( (uint32_t) ((fields+1)* sizeof(Field*)))))
1316
 
  {
1317
 
    goto err;
1318
 
  }
1319
 
 
1320
 
  outparam.field= field_ptr;
1321
 
 
1322
 
  record= (unsigned char*) outparam.record[0]-1;        /* Fieldstart = 1 */
1323
 
 
1324
 
  outparam.null_flags= (unsigned char*) record+1;
1325
 
 
1326
 
  /* Setup copy of fields from share, but use the right alias and record */
1327
 
  for (uint32_t i= 0 ; i < fields; i++, field_ptr++)
1328
 
  {
1329
 
    if (!((*field_ptr)= field[i]->clone(&outparam.mem_root, &outparam)))
1330
 
      goto err;
1331
 
  }
1332
 
  (*field_ptr)= 0;                              // End marker
1333
 
 
1334
 
  if (found_next_number_field)
1335
 
    outparam.found_next_number_field=
1336
 
      outparam.field[(uint32_t) (found_next_number_field - field)];
1337
 
  if (timestamp_field)
1338
 
    outparam.timestamp_field= (Field_timestamp*) outparam.field[timestamp_field_offset];
1339
 
 
1340
 
 
1341
 
  /* Fix key->name and key_part->field */
1342
 
  if (key_parts)
1343
 
  {
1344
 
    KEY *local_key_info, *key_info_end;
1345
 
    KEY_PART_INFO *key_part;
1346
 
    uint32_t n_length;
1347
 
    n_length= keys*sizeof(KEY) + key_parts*sizeof(KEY_PART_INFO);
1348
 
    if (!(local_key_info= (KEY*) outparam.mem_root.alloc_root(n_length)))
1349
 
      goto err;
1350
 
    outparam.key_info= local_key_info;
1351
 
    key_part= (reinterpret_cast<KEY_PART_INFO*> (local_key_info+keys));
1352
 
 
1353
 
    memcpy(local_key_info, key_info, sizeof(*local_key_info)*keys);
1354
 
    memcpy(key_part, key_info[0].key_part, (sizeof(*key_part) *
1355
 
                                                   key_parts));
1356
 
 
1357
 
    for (key_info_end= local_key_info + keys ;
1358
 
         local_key_info < key_info_end ;
1359
 
         local_key_info++)
1360
 
    {
1361
 
      KEY_PART_INFO *key_part_end;
1362
 
 
1363
 
      local_key_info->table= &outparam;
1364
 
      local_key_info->key_part= key_part;
1365
 
 
1366
 
      for (key_part_end= key_part+ local_key_info->key_parts ;
1367
 
           key_part < key_part_end ;
1368
 
           key_part++)
1369
 
      {
1370
 
        Field *local_field= key_part->field= outparam.field[key_part->fieldnr-1];
1371
 
 
1372
 
        if (local_field->key_length() != key_part->length &&
1373
 
            !(local_field->flags & BLOB_FLAG))
1374
 
        {
1375
 
          /*
1376
 
            We are using only a prefix of the column as a key:
1377
 
            Create a new field for the key part that matches the index
1378
 
          */
1379
 
          local_field= key_part->field= local_field->new_field(&outparam.mem_root, &outparam, 0);
1380
 
          local_field->field_length= key_part->length;
1381
 
        }
1382
 
      }
1383
 
    }
1384
 
  }
1385
 
 
1386
 
  /* Allocate bitmaps */
1387
 
 
1388
 
  bitmap_size= column_bitmap_size;
1389
 
  if (!(bitmaps= (unsigned char*) outparam.mem_root.alloc_root(bitmap_size*3)))
1390
 
  {
1391
 
    goto err;
1392
 
  }
1393
 
  outparam.def_read_set.init((my_bitmap_map*) bitmaps, fields);
1394
 
  outparam.def_write_set.init((my_bitmap_map*) (bitmaps+bitmap_size), fields);
1395
 
  outparam.tmp_set.init((my_bitmap_map*) (bitmaps+bitmap_size*2), fields);
1396
 
  outparam.default_column_bitmaps();
1397
 
 
1398
 
  /* The table struct is now initialized;  Open the table */
1399
 
  local_error= 2;
1400
 
  if (db_stat)
1401
 
  {
1402
 
    int ha_err;
1403
 
    if ((ha_err= (outparam.cursor->
1404
 
                  ha_open(&outparam, getNormalizedPath(),
1405
 
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1406
 
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1407
 
                           (db_stat & HA_WAIT_IF_LOCKED) ?  HA_OPEN_WAIT_IF_LOCKED :
1408
 
                           (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1409
 
                           HA_OPEN_ABORT_IF_LOCKED :
1410
 
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1411
 
    {
1412
 
      switch (ha_err)
1413
 
      {
1414
 
        case HA_ERR_NO_SUCH_TABLE:
1415
 
          /*
1416
 
            The table did not exists in storage engine, use same error message
1417
 
            as if the .frm cursor didn't exist
1418
 
          */
1419
 
          local_error= 1;
1420
 
          errno= ENOENT;
1421
 
          break;
1422
 
        case EMFILE:
1423
 
          /*
1424
 
            Too many files opened, use same error message as if the .frm
1425
 
            cursor can't open
1426
 
           */
1427
 
          local_error= 1;
1428
 
          errno= EMFILE;
1429
 
          break;
1430
 
        default:
1431
 
          outparam.print_error(ha_err, MYF(0));
1432
 
          error_reported= true;
1433
 
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1434
 
            local_error= 7;
1435
 
          break;
1436
 
      }
1437
 
      goto err;
1438
 
    }
1439
 
  }
1440
 
 
1441
 
#if defined(HAVE_purify)
1442
 
  memset(bitmaps, 0, bitmap_size*3);
1443
 
#endif
1444
 
 
1445
 
  return 0;
1446
 
 
1447
 
 err:
1448
 
  if (!error_reported)
1449
 
    open_table_error(local_error, errno, 0);
1450
 
 
1451
 
  delete outparam.cursor;
1452
 
  outparam.cursor= 0;                           // For easier error checking
1453
 
  outparam.db_stat= 0;
1454
 
  outparam.mem_root.free_root(MYF(0));       // Safe to call on zeroed root
1455
 
  free((char*) outparam.alias);
1456
 
  return (local_error);
1457
 
}
1458
 
 
1459
 
bool Table::fill_item_list(List<Item> *item_list) const
1460
 
{
1461
 
  /*
1462
 
    All Item_field's created using a direct pointer to a field
1463
 
    are fixed in Item_field constructor.
1464
 
  */
1465
 
  for (Field **ptr= field; *ptr; ptr++)
1466
 
  {
1467
 
    Item_field *item= new Item_field(*ptr);
1468
 
    if (!item || item_list->push_back(item))
1469
 
      return true;
1470
 
  }
1471
 
  return false;
1472
 
}
1473
 
 
1474
77
// @note this should all be the destructor
1475
78
int Table::delete_table(bool free_share)
1476
79
{
1610
213
}
1611
214
 
1612
215
 
1613
 
        /* error message when opening a form cursor */
1614
 
 
1615
 
void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
1616
 
{
1617
 
  int err_no;
1618
 
  char buff[FN_REFLEN];
1619
 
  myf errortype= ME_ERROR+ME_WAITTANG;
1620
 
 
1621
 
  switch (pass_error) {
1622
 
  case 7:
1623
 
  case 1:
1624
 
    if (db_errno == ENOENT)
1625
 
    {
1626
 
      my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str);
1627
 
    }
1628
 
    else
1629
 
    {
1630
 
      snprintf(buff, sizeof(buff), "%s",normalized_path.str);
1631
 
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1632
 
               errortype, buff, db_errno);
1633
 
    }
1634
 
    break;
1635
 
  case 2:
1636
 
  {
1637
 
    Cursor *cursor= 0;
1638
 
    const char *datext= "";
1639
 
 
1640
 
    if (db_type() != NULL)
1641
 
    {
1642
 
      if ((cursor= db_type()->getCursor(*this, current_session->mem_root)))
1643
 
      {
1644
 
        if (!(datext= *db_type()->bas_ext()))
1645
 
          datext= "";
1646
 
      }
1647
 
    }
1648
 
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1649
 
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1650
 
    snprintf(buff, sizeof(buff), "%s%s", normalized_path.str,datext);
1651
 
    my_error(err_no,errortype, buff, db_errno);
1652
 
    delete cursor;
1653
 
    break;
1654
 
  }
1655
 
  case 5:
1656
 
  {
1657
 
    const char *csname= get_charset_name((uint32_t) pass_errarg);
1658
 
    char tmp[10];
1659
 
    if (!csname || csname[0] =='?')
1660
 
    {
1661
 
      snprintf(tmp, sizeof(tmp), "#%d", pass_errarg);
1662
 
      csname= tmp;
1663
 
    }
1664
 
    my_printf_error(ER_UNKNOWN_COLLATION,
1665
 
                    _("Unknown collation '%s' in table '%-.64s' definition"),
1666
 
                    MYF(0), csname, table_name.str);
1667
 
    break;
1668
 
  }
1669
 
  case 6:
1670
 
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
1671
 
    my_printf_error(ER_NOT_FORM_FILE,
1672
 
                    _("Table '%-.64s' was created with a different version "
1673
 
                    "of Drizzle and cannot be read"),
1674
 
                    MYF(0), buff);
1675
 
    break;
1676
 
  case 8:
1677
 
    break;
1678
 
  default:                              /* Better wrong error than none */
1679
 
  case 4:
1680
 
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
1681
 
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1682
 
    break;
1683
 
  }
1684
 
  return;
1685
 
} /* open_table_error */
1686
 
 
1687
 
 
1688
216
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
1689
217
{
1690
218
  TYPELIB *result= (TYPELIB*) mem_root->alloc_root(sizeof(TYPELIB));
3484
2012
}
3485
2013
 
3486
2014
 
 
2015
bool Table::fill_item_list(List<Item> *item_list) const
 
2016
{
 
2017
  /*
 
2018
    All Item_field's created using a direct pointer to a field
 
2019
    are fixed in Item_field constructor.
 
2020
  */
 
2021
  for (Field **ptr= field; *ptr; ptr++)
 
2022
  {
 
2023
    Item_field *item= new Item_field(*ptr);
 
2024
    if (!item || item_list->push_back(item))
 
2025
      return true;
 
2026
  }
 
2027
  return false;
 
2028
}
 
2029
 
3487
2030
/*
3488
2031
  Used by ALTER Table when the table is a temporary one. It changes something
3489
2032
  only if the ALTER contained a RENAME clause (otherwise, table_name is the old