~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2010-11-08 18:24:58 UTC
  • mto: (1921.1.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 1916.
  • Revision ID: brian@tangent.org-20101108182458-twv4hyix43ojno80
Merge in changes such that lock is now broken out into its own directory.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
15
 
16
16
 
17
17
/* Some general useful functions */
54
54
#include <drizzled/item/null.h>
55
55
#include <drizzled/temporal.h>
56
56
 
 
57
#include "drizzled/table/instance.h"
 
58
 
57
59
#include "drizzled/table_proto.h"
58
60
 
59
61
using namespace std;
72
74
 
73
75
/*************************************************************************/
74
76
 
75
 
/* Get column name from column hash */
76
 
 
77
 
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
78
 
{
79
 
  *length= (uint32_t) strlen((*buff)->field_name);
80
 
  return (unsigned char*) (*buff)->field_name;
81
 
}
82
 
 
83
 
/*
84
 
  Allocate a setup TableShare structure
85
 
 
86
 
  SYNOPSIS
87
 
    alloc_table_share()
88
 
    TableList           Take database and table name from there
89
 
    key                 Table cache key (db \0 table_name \0...)
90
 
    key_length          Length of key
91
 
 
92
 
  RETURN
93
 
    0  Error (out of memory)
94
 
    #  Share
95
 
*/
96
 
 
97
 
TableShare *alloc_table_share(TableList *table_list, char *key,
98
 
                               uint32_t key_length)
99
 
{
100
 
  memory::Root mem_root;
101
 
  TableShare *share;
102
 
  char *key_buff, *path_buff;
103
 
  std::string path;
104
 
 
105
 
  build_table_filename(path, table_list->db, table_list->table_name, false);
106
 
 
107
 
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
108
 
  if (multi_alloc_root(&mem_root,
109
 
                       &share, sizeof(*share),
110
 
                       &key_buff, key_length,
111
 
                       &path_buff, path.length() + 1,
112
 
                       NULL))
113
 
  {
114
 
    memset(share, 0, sizeof(*share));
115
 
 
116
 
    share->set_table_cache_key(key_buff, key, key_length);
117
 
 
118
 
    share->path.str= path_buff,
119
 
    share->path.length= path.length();
120
 
    strcpy(share->path.str, path.c_str());
121
 
    share->normalized_path.str=    share->path.str;
122
 
    share->normalized_path.length= path.length();
123
 
 
124
 
    share->version=       refresh_version;
125
 
 
126
 
    memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
127
 
    pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
128
 
    pthread_cond_init(&share->cond, NULL);
129
 
  }
130
 
  return(share);
131
 
}
132
 
 
133
 
 
134
 
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
135
 
{
136
 
  enum_field_types field_type;
137
 
 
138
 
  switch(proto_field_type)
139
 
  {
140
 
  case message::Table::Field::INTEGER:
141
 
    field_type= DRIZZLE_TYPE_LONG;
142
 
    break;
143
 
  case message::Table::Field::DOUBLE:
144
 
    field_type= DRIZZLE_TYPE_DOUBLE;
145
 
    break;
146
 
  case message::Table::Field::TIMESTAMP:
147
 
    field_type= DRIZZLE_TYPE_TIMESTAMP;
148
 
    break;
149
 
  case message::Table::Field::BIGINT:
150
 
    field_type= DRIZZLE_TYPE_LONGLONG;
151
 
    break;
152
 
  case message::Table::Field::DATETIME:
153
 
    field_type= DRIZZLE_TYPE_DATETIME;
154
 
    break;
155
 
  case message::Table::Field::DATE:
156
 
    field_type= DRIZZLE_TYPE_DATE;
157
 
    break;
158
 
  case message::Table::Field::VARCHAR:
159
 
    field_type= DRIZZLE_TYPE_VARCHAR;
160
 
    break;
161
 
  case message::Table::Field::DECIMAL:
162
 
    field_type= DRIZZLE_TYPE_DECIMAL;
163
 
    break;
164
 
  case message::Table::Field::ENUM:
165
 
    field_type= DRIZZLE_TYPE_ENUM;
166
 
    break;
167
 
  case message::Table::Field::BLOB:
168
 
    field_type= DRIZZLE_TYPE_BLOB;
169
 
    break;
170
 
  default:
171
 
    field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
172
 
    assert(1);
173
 
  }
174
 
 
175
 
  return field_type;
176
 
}
177
 
 
178
 
static Item *default_value_item(enum_field_types field_type,
179
 
                                const CHARSET_INFO *charset,
180
 
                                bool default_null, const string *default_value,
181
 
                                const string *default_bin_value)
182
 
{
183
 
  Item *default_item= NULL;
184
 
  int error= 0;
185
 
 
186
 
  if (default_null)
187
 
  {
188
 
    return new Item_null();
189
 
  }
190
 
 
191
 
  switch(field_type)
192
 
  {
193
 
  case DRIZZLE_TYPE_LONG:
194
 
  case DRIZZLE_TYPE_LONGLONG:
195
 
    default_item= new Item_int(default_value->c_str(),
196
 
                               (int64_t) internal::my_strtoll10(default_value->c_str(),
197
 
                                                                NULL,
198
 
                                                                &error),
199
 
                               default_value->length());
200
 
    break;
201
 
  case DRIZZLE_TYPE_DOUBLE:
202
 
    default_item= new Item_float(default_value->c_str(),
203
 
                                 default_value->length());
204
 
    break;
205
 
  case DRIZZLE_TYPE_NULL:
206
 
    assert(false);
207
 
  case DRIZZLE_TYPE_TIMESTAMP:
208
 
  case DRIZZLE_TYPE_DATETIME:
209
 
  case DRIZZLE_TYPE_DATE:
210
 
    if (default_value->compare("NOW()") == 0)
211
 
      break;
212
 
  case DRIZZLE_TYPE_ENUM:
213
 
    default_item= new Item_string(default_value->c_str(),
214
 
                                  default_value->length(),
215
 
                                  system_charset_info);
216
 
    break;
217
 
  case DRIZZLE_TYPE_VARCHAR:
218
 
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
219
 
    if (charset==&my_charset_bin)
220
 
    {
221
 
      default_item= new Item_string(default_bin_value->c_str(),
222
 
                                    default_bin_value->length(),
223
 
                                    &my_charset_bin);
224
 
    }
225
 
    else
226
 
    {
227
 
      default_item= new Item_string(default_value->c_str(),
228
 
                                    default_value->length(),
229
 
                                    system_charset_info);
230
 
    }
231
 
    break;
232
 
  case DRIZZLE_TYPE_DECIMAL:
233
 
    default_item= new Item_decimal(default_value->c_str(),
234
 
                                   default_value->length(),
235
 
                                   system_charset_info);
236
 
    break;
237
 
  }
238
 
 
239
 
  return default_item;
240
 
}
241
 
 
242
 
int parse_table_proto(Session& session,
243
 
                      message::Table &table,
244
 
                      TableShare *share)
245
 
{
246
 
  int error= 0;
247
 
 
248
 
  if (! table.IsInitialized())
249
 
  {
250
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table.InitializationErrorString().c_str());
251
 
    return ER_CORRUPT_TABLE_DEFINITION;
252
 
  }
253
 
 
254
 
  share->setTableProto(new(nothrow) message::Table(table));
255
 
 
256
 
  share->storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
257
 
  assert(share->storage_engine); // We use an assert() here because we should never get this far and still have no suitable engine.
258
 
 
259
 
  message::Table::TableOptions table_options;
260
 
 
261
 
  if (table.has_options())
262
 
    table_options= table.options();
263
 
 
264
 
  uint32_t db_create_options= 0;
265
 
 
266
 
  if (table_options.has_pack_keys())
267
 
  {
268
 
    if (table_options.pack_keys())
269
 
      db_create_options|= HA_OPTION_PACK_KEYS;
270
 
    else
271
 
      db_create_options|= HA_OPTION_NO_PACK_KEYS;
272
 
  }
273
 
 
274
 
  if (table_options.pack_record())
275
 
    db_create_options|= HA_OPTION_PACK_RECORD;
276
 
 
277
 
  /* db_create_options was stored as 2 bytes in FRM
278
 
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
279
 
   */
280
 
  share->db_create_options= (db_create_options & 0x0000FFFF);
281
 
  share->db_options_in_use= share->db_create_options;
282
 
 
283
 
  share->row_type= table_options.has_row_type() ?
284
 
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
285
 
 
286
 
  share->block_size= table_options.has_block_size() ?
287
 
    table_options.block_size() : 0;
288
 
 
289
 
  share->table_charset= get_charset(table_options.has_collation_id()?
290
 
                                    table_options.collation_id() : 0);
291
 
 
292
 
  if (!share->table_charset)
293
 
  {
294
 
    /* unknown charset in head[38] or pre-3.23 frm */
295
 
    if (use_mb(default_charset_info))
296
 
    {
297
 
      /* Warn that we may be changing the size of character columns */
298
 
      errmsg_printf(ERRMSG_LVL_WARN,
299
 
                    _("'%s' had no or invalid character set, "
300
 
                      "and default character set is multi-byte, "
301
 
                      "so character column sizes may have changed"),
302
 
                    share->path.str);
303
 
    }
304
 
    share->table_charset= default_charset_info;
305
 
  }
306
 
 
307
 
  share->db_record_offset= 1;
308
 
 
309
 
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
310
 
 
311
 
  share->keys= table.indexes_size();
312
 
 
313
 
  share->key_parts= 0;
314
 
  for (int indx= 0; indx < table.indexes_size(); indx++)
315
 
    share->key_parts+= table.indexes(indx).index_part_size();
316
 
 
317
 
  share->key_info= (KEY*) alloc_root(&share->mem_root,
318
 
                                     table.indexes_size() * sizeof(KEY)
319
 
                                     +share->key_parts*sizeof(KEY_PART_INFO));
320
 
 
321
 
  KEY_PART_INFO *key_part;
322
 
 
323
 
  key_part= reinterpret_cast<KEY_PART_INFO*>
324
 
    (share->key_info+table.indexes_size());
325
 
 
326
 
 
327
 
  ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
328
 
                                            sizeof(ulong*)*share->key_parts);
329
 
 
330
 
  share->keynames.count= table.indexes_size();
331
 
  share->keynames.name= NULL;
332
 
  share->keynames.type_names= (const char**)
333
 
    alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
334
 
 
335
 
  share->keynames.type_lengths= (unsigned int*)
336
 
    alloc_root(&share->mem_root,
337
 
               sizeof(unsigned int) * (table.indexes_size()+1));
338
 
 
339
 
  share->keynames.type_names[share->keynames.count]= NULL;
340
 
  share->keynames.type_lengths[share->keynames.count]= 0;
341
 
 
342
 
  KEY* keyinfo= share->key_info;
343
 
  for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
344
 
  {
345
 
    message::Table::Index indx= table.indexes(keynr);
346
 
 
347
 
    keyinfo->table= 0;
348
 
    keyinfo->flags= 0;
349
 
 
350
 
    if (indx.is_unique())
351
 
      keyinfo->flags|= HA_NOSAME;
352
 
 
353
 
    if (indx.has_options())
354
 
    {
355
 
      message::Table::Index::IndexOptions indx_options= indx.options();
356
 
      if (indx_options.pack_key())
357
 
        keyinfo->flags|= HA_PACK_KEY;
358
 
 
359
 
      if (indx_options.var_length_key())
360
 
        keyinfo->flags|= HA_VAR_LENGTH_PART;
361
 
 
362
 
      if (indx_options.null_part_key())
363
 
        keyinfo->flags|= HA_NULL_PART_KEY;
364
 
 
365
 
      if (indx_options.binary_pack_key())
366
 
        keyinfo->flags|= HA_BINARY_PACK_KEY;
367
 
 
368
 
      if (indx_options.has_partial_segments())
369
 
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
370
 
 
371
 
      if (indx_options.auto_generated_key())
372
 
        keyinfo->flags|= HA_GENERATED_KEY;
373
 
 
374
 
      if (indx_options.has_key_block_size())
375
 
      {
376
 
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
377
 
        keyinfo->block_size= indx_options.key_block_size();
378
 
      }
379
 
      else
380
 
      {
381
 
        keyinfo->block_size= 0;
382
 
      }
383
 
    }
384
 
 
385
 
    switch (indx.type())
386
 
    {
387
 
    case message::Table::Index::UNKNOWN_INDEX:
388
 
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
389
 
      break;
390
 
    case message::Table::Index::BTREE:
391
 
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
392
 
      break;
393
 
    case message::Table::Index::HASH:
394
 
      keyinfo->algorithm= HA_KEY_ALG_HASH;
395
 
      break;
396
 
 
397
 
    default:
398
 
      /* TODO: suitable warning ? */
399
 
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
400
 
      break;
401
 
    }
402
 
 
403
 
    keyinfo->key_length= indx.key_length();
404
 
 
405
 
    keyinfo->key_parts= indx.index_part_size();
406
 
 
407
 
    keyinfo->key_part= key_part;
408
 
    keyinfo->rec_per_key= rec_per_key;
409
 
 
410
 
    for (unsigned int partnr= 0;
411
 
         partnr < keyinfo->key_parts;
412
 
         partnr++, key_part++)
413
 
    {
414
 
      message::Table::Index::IndexPart part;
415
 
      part= indx.index_part(partnr);
416
 
 
417
 
      *rec_per_key++= 0;
418
 
 
419
 
      key_part->field= NULL;
420
 
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
421
 
      key_part->null_bit= 0;
422
 
      /* key_part->null_offset is only set if null_bit (see later) */
423
 
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
424
 
      /* key_part->type ???? */
425
 
      key_part->key_part_flag= 0;
426
 
      if (part.has_in_reverse_order())
427
 
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
428
 
 
429
 
      key_part->length= part.compare_length();
430
 
 
431
 
      key_part->store_length= key_part->length;
432
 
 
433
 
      /* key_part->offset is set later */
434
 
      key_part->key_type= part.key_type();
435
 
    }
436
 
 
437
 
    if (! indx.has_comment())
438
 
    {
439
 
      keyinfo->comment.length= 0;
440
 
      keyinfo->comment.str= NULL;
441
 
    }
442
 
    else
443
 
    {
444
 
      keyinfo->flags|= HA_USES_COMMENT;
445
 
      keyinfo->comment.length= indx.comment().length();
446
 
      keyinfo->comment.str= strmake_root(&share->mem_root,
447
 
                                         indx.comment().c_str(),
448
 
                                         keyinfo->comment.length);
449
 
    }
450
 
 
451
 
    keyinfo->name= strmake_root(&share->mem_root,
452
 
                                indx.name().c_str(),
453
 
                                indx.name().length());
454
 
 
455
 
    share->keynames.type_names[keynr]= keyinfo->name;
456
 
    share->keynames.type_lengths[keynr]= indx.name().length();
457
 
  }
458
 
 
459
 
  share->keys_for_keyread.reset();
460
 
  set_prefix(share->keys_in_use, share->keys);
461
 
 
462
 
  share->fields= table.field_size();
463
 
 
464
 
  share->field= (Field**) alloc_root(&share->mem_root,
465
 
                                     ((share->fields+1) * sizeof(Field*)));
466
 
  share->field[share->fields]= NULL;
467
 
 
468
 
  uint32_t null_fields= 0;
469
 
  share->reclength= 0;
470
 
 
471
 
  uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
472
 
  uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
473
 
 
474
 
  assert(field_offsets && field_pack_length); // TODO: fixme
475
 
 
476
 
  uint32_t interval_count= 0;
477
 
  uint32_t interval_parts= 0;
478
 
 
479
 
  uint32_t stored_columns_reclength= 0;
480
 
 
481
 
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
482
 
  {
483
 
    message::Table::Field pfield= table.field(fieldnr);
484
 
    if (pfield.constraints().is_nullable())
485
 
      null_fields++;
486
 
 
487
 
    enum_field_types drizzle_field_type=
488
 
      proto_field_type_to_drizzle_type(pfield.type());
489
 
 
490
 
    field_offsets[fieldnr]= stored_columns_reclength;
491
 
 
492
 
    /* the below switch is very similar to
493
 
       CreateField::create_length_to_internal_length in field.cc
494
 
       (which should one day be replace by just this code)
495
 
    */
496
 
    switch(drizzle_field_type)
497
 
    {
498
 
    case DRIZZLE_TYPE_BLOB:
499
 
    case DRIZZLE_TYPE_VARCHAR:
500
 
      {
501
 
        message::Table::Field::StringFieldOptions field_options= pfield.string_options();
502
 
 
503
 
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id() ?
504
 
                                            field_options.collation_id() : 0);
505
 
 
506
 
        if (! cs)
507
 
          cs= default_charset_info;
508
 
 
509
 
        field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type,
510
 
                                                     field_options.length() * cs->mbmaxlen);
511
 
      }
512
 
      break;
513
 
    case DRIZZLE_TYPE_ENUM:
514
 
      {
515
 
        message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
516
 
 
517
 
        field_pack_length[fieldnr]=
518
 
          get_enum_pack_length(field_options.field_value_size());
519
 
 
520
 
        interval_count++;
521
 
        interval_parts+= field_options.field_value_size();
522
 
      }
523
 
      break;
524
 
    case DRIZZLE_TYPE_DECIMAL:
525
 
      {
526
 
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
527
 
 
528
 
        field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
529
 
      }
530
 
      break;
531
 
    default:
532
 
      /* Zero is okay here as length is fixed for other types. */
533
 
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
534
 
    }
535
 
 
536
 
    share->reclength+= field_pack_length[fieldnr];
537
 
    stored_columns_reclength+= field_pack_length[fieldnr];
538
 
  }
539
 
 
540
 
  /* data_offset added to stored_rec_length later */
541
 
  share->stored_rec_length= stored_columns_reclength;
542
 
 
543
 
  share->null_fields= null_fields;
544
 
 
545
 
  ulong null_bits= null_fields;
546
 
  if (! table_options.pack_record())
547
 
    null_bits++;
548
 
  ulong data_offset= (null_bits + 7)/8;
549
 
 
550
 
 
551
 
  share->reclength+= data_offset;
552
 
  share->stored_rec_length+= data_offset;
553
 
 
554
 
  ulong rec_buff_length;
555
 
 
556
 
  rec_buff_length= ALIGN_SIZE(share->reclength + 1);
557
 
  share->rec_buff_length= rec_buff_length;
558
 
 
559
 
  unsigned char* record= NULL;
560
 
 
561
 
  if (! (record= (unsigned char *) alloc_root(&share->mem_root,
562
 
                                              rec_buff_length)))
563
 
    abort();
564
 
 
565
 
  memset(record, 0, rec_buff_length);
566
 
 
567
 
  int null_count= 0;
568
 
 
569
 
  if (! table_options.pack_record())
570
 
  {
571
 
    null_count++; // one bit for delete mark.
572
 
    *record|= 1;
573
 
  }
574
 
 
575
 
  share->default_values= record;
576
 
 
577
 
  if (interval_count)
578
 
  {
579
 
    share->intervals= (TYPELIB *) alloc_root(&share->mem_root,
580
 
                                           interval_count*sizeof(TYPELIB));
581
 
  }
582
 
  else
583
 
    share->intervals= NULL;
584
 
 
585
 
  share->fieldnames.type_names= (const char **) alloc_root(&share->mem_root,
586
 
                                                          (share->fields + 1) * sizeof(char*));
587
 
 
588
 
  share->fieldnames.type_lengths= (unsigned int *) alloc_root(&share->mem_root,
589
 
                                                             (share->fields + 1) * sizeof(unsigned int));
590
 
 
591
 
  share->fieldnames.type_names[share->fields]= NULL;
592
 
  share->fieldnames.type_lengths[share->fields]= 0;
593
 
  share->fieldnames.count= share->fields;
594
 
 
595
 
 
596
 
  /* Now fix the TYPELIBs for the intervals (enum values)
597
 
     and field names.
598
 
   */
599
 
 
600
 
  uint32_t interval_nr= 0;
601
 
 
602
 
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
603
 
  {
604
 
    message::Table::Field pfield= table.field(fieldnr);
605
 
 
606
 
    /* field names */
607
 
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
608
 
                                                        pfield.name().c_str(),
609
 
                                                        pfield.name().length());
610
 
 
611
 
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
612
 
 
613
 
    /* enum typelibs */
614
 
    if (pfield.type() != message::Table::Field::ENUM)
615
 
      continue;
616
 
 
617
 
    message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
618
 
 
619
 
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id() ?
620
 
                                             field_options.collation_id() : 0);
621
 
 
622
 
    if (! charset)
623
 
      charset= default_charset_info;
624
 
 
625
 
    TYPELIB *t= &(share->intervals[interval_nr]);
626
 
 
627
 
    t->type_names= (const char**)alloc_root(&share->mem_root,
628
 
                                            (field_options.field_value_size() + 1) * sizeof(char*));
629
 
 
630
 
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
631
 
                                                (field_options.field_value_size() + 1) * sizeof(unsigned int));
632
 
 
633
 
    t->type_names[field_options.field_value_size()]= NULL;
634
 
    t->type_lengths[field_options.field_value_size()]= 0;
635
 
 
636
 
    t->count= field_options.field_value_size();
637
 
    t->name= NULL;
638
 
 
639
 
    for (int n= 0; n < field_options.field_value_size(); n++)
640
 
    {
641
 
      t->type_names[n]= strmake_root(&share->mem_root,
642
 
                                     field_options.field_value(n).c_str(),
643
 
                                     field_options.field_value(n).length());
644
 
 
645
 
      /* 
646
 
       * Go ask the charset what the length is as for "" length=1
647
 
       * and there's stripping spaces or some other crack going on.
648
 
       */
649
 
      uint32_t lengthsp;
650
 
      lengthsp= charset->cset->lengthsp(charset,
651
 
                                        t->type_names[n],
652
 
                                        field_options.field_value(n).length());
653
 
      t->type_lengths[n]= lengthsp;
654
 
    }
655
 
    interval_nr++;
656
 
  }
657
 
 
658
 
 
659
 
  /* and read the fields */
660
 
  interval_nr= 0;
661
 
 
662
 
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
663
 
 
664
 
  if (use_hash)
665
 
    use_hash= ! hash_init(&share->name_hash,
666
 
                          system_charset_info,
667
 
                          share->fields,
668
 
                          0,
669
 
                          0,
670
 
                          (hash_get_key) get_field_name,
671
 
                          0,
672
 
                          0);
673
 
 
674
 
  unsigned char* null_pos= record;;
675
 
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
676
 
 
677
 
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
678
 
  {
679
 
    message::Table::Field pfield= table.field(fieldnr);
680
 
 
681
 
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
682
 
 
683
 
    switch (pfield.format())
684
 
    {
685
 
    case message::Table::Field::DefaultFormat:
686
 
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
687
 
      break;
688
 
    case message::Table::Field::FixedFormat:
689
 
      column_format= COLUMN_FORMAT_TYPE_FIXED;
690
 
      break;
691
 
    case message::Table::Field::DynamicFormat:
692
 
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
693
 
      break;
694
 
    default:
695
 
      assert(1);
696
 
    }
697
 
 
698
 
    Field::utype unireg_type= Field::NONE;
699
 
 
700
 
    if (pfield.has_numeric_options() &&
701
 
        pfield.numeric_options().is_autoincrement())
702
 
    {
703
 
      unireg_type= Field::NEXT_NUMBER;
704
 
    }
705
 
 
706
 
    if (pfield.has_options() &&
707
 
        pfield.options().has_default_value() &&
708
 
        pfield.options().default_value().compare("NOW()") == 0)
709
 
    {
710
 
      if (pfield.options().has_update_value() &&
711
 
          pfield.options().update_value().compare("NOW()") == 0)
712
 
      {
713
 
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
714
 
      }
715
 
      else if (! pfield.options().has_update_value())
716
 
      {
717
 
        unireg_type= Field::TIMESTAMP_DN_FIELD;
718
 
      }
719
 
      else
720
 
        assert(1); // Invalid update value.
721
 
    }
722
 
    else if (pfield.has_options() &&
723
 
             pfield.options().has_update_value() &&
724
 
             pfield.options().update_value().compare("NOW()") == 0)
725
 
    {
726
 
      unireg_type= Field::TIMESTAMP_UN_FIELD;
727
 
    }
728
 
 
729
 
    LEX_STRING comment;
730
 
    if (!pfield.has_comment())
731
 
    {
732
 
      comment.str= (char*)"";
733
 
      comment.length= 0;
734
 
    }
735
 
    else
736
 
    {
737
 
      size_t len= pfield.comment().length();
738
 
      const char* str= pfield.comment().c_str();
739
 
 
740
 
      comment.str= strmake_root(&share->mem_root, str, len);
741
 
      comment.length= len;
742
 
    }
743
 
 
744
 
    enum_field_types field_type;
745
 
 
746
 
    field_type= proto_field_type_to_drizzle_type(pfield.type());
747
 
 
748
 
    const CHARSET_INFO *charset= &my_charset_bin;
749
 
 
750
 
    if (field_type == DRIZZLE_TYPE_BLOB ||
751
 
        field_type == DRIZZLE_TYPE_VARCHAR)
752
 
    {
753
 
      message::Table::Field::StringFieldOptions field_options= pfield.string_options();
754
 
 
755
 
      charset= get_charset(field_options.has_collation_id() ?
756
 
                           field_options.collation_id() : 0);
757
 
 
758
 
      if (! charset)
759
 
        charset= default_charset_info;
760
 
    }
761
 
 
762
 
    if (field_type == DRIZZLE_TYPE_ENUM)
763
 
    {
764
 
      message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
765
 
 
766
 
      charset= get_charset(field_options.has_collation_id()?
767
 
                           field_options.collation_id() : 0);
768
 
 
769
 
      if (! charset)
770
 
              charset= default_charset_info;
771
 
    }
772
 
 
773
 
    uint8_t decimals= 0;
774
 
    if (field_type == DRIZZLE_TYPE_DECIMAL
775
 
        || field_type == DRIZZLE_TYPE_DOUBLE)
776
 
    {
777
 
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
778
 
 
779
 
      if (! pfield.has_numeric_options() || ! fo.has_scale())
780
 
      {
781
 
        /*
782
 
          We don't write the default to table proto so
783
 
          if no decimals specified for DOUBLE, we use the default.
784
 
        */
785
 
        decimals= NOT_FIXED_DEC;
786
 
      }
787
 
      else
788
 
      {
789
 
        if (fo.scale() > DECIMAL_MAX_SCALE)
790
 
        {
791
 
          error= 4;
792
 
          goto err;
793
 
        }
794
 
        decimals= static_cast<uint8_t>(fo.scale());
795
 
      }
796
 
    }
797
 
 
798
 
    Item *default_value= NULL;
799
 
 
800
 
    if (pfield.options().has_default_value() ||
801
 
        pfield.options().has_default_null()  ||
802
 
        pfield.options().has_default_bin_value())
803
 
    {
804
 
      default_value= default_value_item(field_type,
805
 
                                        charset,
806
 
                                        pfield.options().default_null(),
807
 
                                        &pfield.options().default_value(),
808
 
                                        &pfield.options().default_bin_value());
809
 
    }
810
 
 
811
 
 
812
 
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
813
 
    memset(&temp_table, 0, sizeof(temp_table));
814
 
    temp_table.s= share;
815
 
    temp_table.in_use= &session;
816
 
    temp_table.s->db_low_byte_first= true; //Cursor->low_byte_first();
817
 
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
818
 
 
819
 
    uint32_t field_length= 0; //Assignment is for compiler complaint.
820
 
 
821
 
    switch (field_type)
822
 
    {
823
 
    case DRIZZLE_TYPE_BLOB:
824
 
    case DRIZZLE_TYPE_VARCHAR:
825
 
    {
826
 
      message::Table::Field::StringFieldOptions field_options= pfield.string_options();
827
 
 
828
 
      charset= get_charset(field_options.has_collation_id() ?
829
 
                           field_options.collation_id() : 0);
830
 
 
831
 
      if (! charset)
832
 
        charset= default_charset_info;
833
 
 
834
 
      field_length= field_options.length() * charset->mbmaxlen;
835
 
    }
836
 
      break;
837
 
    case DRIZZLE_TYPE_DOUBLE:
838
 
    {
839
 
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
840
 
      if (!fo.has_precision() && !fo.has_scale())
841
 
      {
842
 
        field_length= DBL_DIG+7;
843
 
      }
844
 
      else
845
 
      {
846
 
        field_length= fo.precision();
847
 
      }
848
 
      if (field_length < decimals &&
849
 
          decimals != NOT_FIXED_DEC)
850
 
      {
851
 
        my_error(ER_M_BIGGER_THAN_D, MYF(0), pfield.name().c_str());
852
 
        error= 1;
853
 
        goto err;
854
 
      }
855
 
      break;
856
 
    }
857
 
    case DRIZZLE_TYPE_DECIMAL:
858
 
    {
859
 
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
860
 
 
861
 
      field_length= my_decimal_precision_to_length(fo.precision(), fo.scale(),
862
 
                                                   false);
863
 
      break;
864
 
    }
865
 
    case DRIZZLE_TYPE_TIMESTAMP:
866
 
    case DRIZZLE_TYPE_DATETIME:
867
 
      field_length= DateTime::MAX_STRING_LENGTH;
868
 
      break;
869
 
    case DRIZZLE_TYPE_DATE:
870
 
      field_length= Date::MAX_STRING_LENGTH;
871
 
      break;
872
 
    case DRIZZLE_TYPE_ENUM:
873
 
    {
874
 
      field_length= 0;
875
 
 
876
 
      message::Table::Field::EnumerationValues fo= pfield.enumeration_values();
877
 
 
878
 
      for (int valnr= 0; valnr < fo.field_value_size(); valnr++)
879
 
      {
880
 
        if (fo.field_value(valnr).length() > field_length)
881
 
        {
882
 
          field_length= charset->cset->numchars(charset,
883
 
                                                fo.field_value(valnr).c_str(),
884
 
                                                fo.field_value(valnr).c_str()
885
 
                                                + fo.field_value(valnr).length())
886
 
            * charset->mbmaxlen;
887
 
        }
888
 
      }
889
 
    }
890
 
    break;
891
 
    case DRIZZLE_TYPE_LONG:
892
 
      {
893
 
        uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
894
 
          field_length= MAX_INT_WIDTH+sign_len;
895
 
      }
896
 
      break;
897
 
    case DRIZZLE_TYPE_LONGLONG:
898
 
      field_length= MAX_BIGINT_WIDTH;
899
 
      break;
900
 
    case DRIZZLE_TYPE_NULL:
901
 
      abort(); // Programming error
902
 
    }
903
 
 
904
 
    Field* f= make_field(share,
905
 
                         &share->mem_root,
906
 
                         record + field_offsets[fieldnr] + data_offset,
907
 
                         field_length,
908
 
                         pfield.constraints().is_nullable(),
909
 
                         null_pos,
910
 
                         null_bit_pos,
911
 
                         decimals,
912
 
                         field_type,
913
 
                         charset,
914
 
                         (Field::utype) MTYP_TYPENR(unireg_type),
915
 
                         ((field_type == DRIZZLE_TYPE_ENUM) ?
916
 
                          share->intervals + (interval_nr++)
917
 
                          : (TYPELIB*) 0),
918
 
                         share->fieldnames.type_names[fieldnr]);
919
 
 
920
 
    share->field[fieldnr]= f;
921
 
 
922
 
    f->init(&temp_table); /* blob default values need table obj */
923
 
 
924
 
    if (! (f->flags & NOT_NULL_FLAG))
925
 
    {
926
 
      *f->null_ptr|= f->null_bit;
927
 
      if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
928
 
        null_pos++;
929
 
      null_count++;
930
 
    }
931
 
 
932
 
    if (default_value)
933
 
    {
934
 
      enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
935
 
      session.count_cuted_fields= CHECK_FIELD_WARN;
936
 
      int res= default_value->save_in_field(f, 1);
937
 
      session.count_cuted_fields= old_count_cuted_fields;
938
 
      if (res != 0 && res != 3) /* @TODO Huh? */
939
 
      {
940
 
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
941
 
        error= 1;
942
 
        goto err;
943
 
      }
944
 
    }
945
 
    else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
946
 
             (f->flags & NOT_NULL_FLAG))
947
 
    {
948
 
      f->set_notnull();
949
 
      f->store((int64_t) 1, true);
950
 
    }
951
 
    else
952
 
      f->reset();
953
 
 
954
 
    /* hack to undo f->init() */
955
 
    f->table= NULL;
956
 
    f->orig_table= NULL;
957
 
 
958
 
    f->field_index= fieldnr;
959
 
    f->comment= comment;
960
 
    if (! default_value &&
961
 
        ! (f->unireg_check==Field::NEXT_NUMBER) &&
962
 
        (f->flags & NOT_NULL_FLAG) &&
963
 
        (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
964
 
    {
965
 
      f->flags|= NO_DEFAULT_VALUE_FLAG;
966
 
    }
967
 
 
968
 
    if (f->unireg_check == Field::NEXT_NUMBER)
969
 
      share->found_next_number_field= &(share->field[fieldnr]);
970
 
 
971
 
    if (share->timestamp_field == f)
972
 
      share->timestamp_field_offset= fieldnr;
973
 
 
974
 
    if (use_hash) /* supposedly this never fails... but comments lie */
975
 
      (void) my_hash_insert(&share->name_hash,
976
 
                            (unsigned char*)&(share->field[fieldnr]));
977
 
 
978
 
  }
979
 
 
980
 
  keyinfo= share->key_info;
981
 
  for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
982
 
  {
983
 
    key_part= keyinfo->key_part;
984
 
 
985
 
    for (unsigned int partnr= 0;
986
 
         partnr < keyinfo->key_parts;
987
 
         partnr++, key_part++)
988
 
    {
989
 
      /* 
990
 
       * Fix up key_part->offset by adding data_offset.
991
 
       * We really should compute offset as well.
992
 
       * But at least this way we are a little better.
993
 
       */
994
 
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
995
 
    }
996
 
  }
997
 
 
998
 
  /*
999
 
    We need to set the unused bits to 1. If the number of bits is a multiple
1000
 
    of 8 there are no unused bits.
1001
 
  */
1002
 
 
1003
 
  if (null_count & 7)
1004
 
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1005
 
 
1006
 
  share->null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
1007
 
 
1008
 
  share->last_null_bit_pos= null_bit_pos;
1009
 
 
1010
 
  free(field_offsets);
1011
 
  field_offsets= NULL;
1012
 
  free(field_pack_length);
1013
 
  field_pack_length= NULL;
1014
 
 
1015
 
  /* Fix key stuff */
1016
 
  if (share->key_parts)
1017
 
  {
1018
 
    uint32_t primary_key= (uint32_t) (find_type((char*) "PRIMARY",
1019
 
                                                &share->keynames, 3) - 1); /* @TODO Huh? */
1020
 
 
1021
 
    keyinfo= share->key_info;
1022
 
    key_part= keyinfo->key_part;
1023
 
 
1024
 
    for (uint32_t key= 0; key < share->keys; key++,keyinfo++)
1025
 
    {
1026
 
      uint32_t usable_parts= 0;
1027
 
 
1028
 
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1029
 
      {
1030
 
        /*
1031
 
          If the UNIQUE key doesn't have NULL columns and is not a part key
1032
 
          declare this as a primary key.
1033
 
        */
1034
 
        primary_key=key;
1035
 
        for (uint32_t i= 0; i < keyinfo->key_parts; i++)
1036
 
        {
1037
 
          uint32_t fieldnr= key_part[i].fieldnr;
1038
 
          if (! fieldnr ||
1039
 
              share->field[fieldnr-1]->null_ptr ||
1040
 
              share->field[fieldnr-1]->key_length() != key_part[i].length)
1041
 
          {
1042
 
            primary_key= MAX_KEY; // Can't be used
1043
 
            break;
1044
 
          }
1045
 
        }
1046
 
      }
1047
 
 
1048
 
      for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
1049
 
      {
1050
 
        Field *field;
1051
 
        if (! key_part->fieldnr)
1052
 
        {
1053
 
          abort(); // goto err;
1054
 
        }
1055
 
        field= key_part->field= share->field[key_part->fieldnr-1];
1056
 
        key_part->type= field->key_type();
1057
 
        if (field->null_ptr)
1058
 
        {
1059
 
          key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1060
 
                                        share->default_values);
1061
 
          key_part->null_bit= field->null_bit;
1062
 
          key_part->store_length+=HA_KEY_NULL_LENGTH;
1063
 
          keyinfo->flags|=HA_NULL_PART_KEY;
1064
 
          keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1065
 
          keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1066
 
        }
1067
 
        if (field->type() == DRIZZLE_TYPE_BLOB ||
1068
 
            field->real_type() == DRIZZLE_TYPE_VARCHAR)
1069
 
        {
1070
 
          if (field->type() == DRIZZLE_TYPE_BLOB)
1071
 
            key_part->key_part_flag|= HA_BLOB_PART;
1072
 
          else
1073
 
            key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1074
 
          keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1075
 
          key_part->store_length+=HA_KEY_BLOB_LENGTH;
1076
 
          keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1077
 
        }
1078
 
        if (i == 0 && key != primary_key)
1079
 
          field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1080
 
                           (keyinfo->key_parts == 1)) ?
1081
 
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1082
 
        if (i == 0)
1083
 
          field->key_start.set(key);
1084
 
        if (field->key_length() == key_part->length &&
1085
 
            !(field->flags & BLOB_FLAG))
1086
 
        {
1087
 
          enum ha_key_alg algo= share->key_info[key].algorithm;
1088
 
          if (share->db_type()->index_flags(algo) & HA_KEYREAD_ONLY)
1089
 
          {
1090
 
            share->keys_for_keyread.set(key);
1091
 
            field->part_of_key.set(key);
1092
 
            field->part_of_key_not_clustered.set(key);
1093
 
          }
1094
 
          if (share->db_type()->index_flags(algo) & HA_READ_ORDER)
1095
 
            field->part_of_sortkey.set(key);
1096
 
        }
1097
 
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1098
 
            usable_parts == i)
1099
 
          usable_parts++;                       // For FILESORT
1100
 
        field->flags|= PART_KEY_FLAG;
1101
 
        if (key == primary_key)
1102
 
        {
1103
 
          field->flags|= PRI_KEY_FLAG;
1104
 
          /*
1105
 
            If this field is part of the primary key and all keys contains
1106
 
            the primary key, then we can use any key to find this column
1107
 
          */
1108
 
          if (share->storage_engine->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX))
1109
 
          {
1110
 
            field->part_of_key= share->keys_in_use;
1111
 
            if (field->part_of_sortkey.test(key))
1112
 
              field->part_of_sortkey= share->keys_in_use;
1113
 
          }
1114
 
        }
1115
 
        if (field->key_length() != key_part->length)
1116
 
        {
1117
 
          key_part->key_part_flag|= HA_PART_KEY_SEG;
1118
 
        }
1119
 
      }
1120
 
      keyinfo->usable_key_parts= usable_parts; // Filesort
1121
 
 
1122
 
      set_if_bigger(share->max_key_length,keyinfo->key_length+
1123
 
                    keyinfo->key_parts);
1124
 
      share->total_key_length+= keyinfo->key_length;
1125
 
 
1126
 
      if (keyinfo->flags & HA_NOSAME)
1127
 
      {
1128
 
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
1129
 
      }
1130
 
    }
1131
 
    if (primary_key < MAX_KEY &&
1132
 
        (share->keys_in_use.test(primary_key)))
1133
 
    {
1134
 
      share->primary_key= primary_key;
1135
 
      /*
1136
 
        If we are using an integer as the primary key then allow the user to
1137
 
        refer to it as '_rowid'
1138
 
      */
1139
 
      if (share->key_info[primary_key].key_parts == 1)
1140
 
      {
1141
 
        Field *field= share->key_info[primary_key].key_part[0].field;
1142
 
        if (field && field->result_type() == INT_RESULT)
1143
 
        {
1144
 
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
1145
 
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1146
 
                                      fieldnr);
1147
 
        }
1148
 
      }
1149
 
    }
1150
 
    else
1151
 
      share->primary_key = MAX_KEY; // we do not have a primary key
1152
 
  }
1153
 
  else
1154
 
    share->primary_key= MAX_KEY;
1155
 
 
1156
 
  if (share->found_next_number_field)
1157
 
  {
1158
 
    Field *reg_field= *share->found_next_number_field;
1159
 
    if ((int) (share->next_number_index= (uint32_t)
1160
 
               find_ref_key(share->key_info, share->keys,
1161
 
                            share->default_values, reg_field,
1162
 
                            &share->next_number_key_offset,
1163
 
                            &share->next_number_keypart)) < 0)
1164
 
    {
1165
 
      /* Wrong field definition */
1166
 
      error= 4;
1167
 
      goto err;
1168
 
    }
1169
 
    else
1170
 
      reg_field->flags |= AUTO_INCREMENT_FLAG;
1171
 
  }
1172
 
 
1173
 
  if (share->blob_fields)
1174
 
  {
1175
 
    Field **ptr;
1176
 
    uint32_t k, *save;
1177
 
 
1178
 
    /* Store offsets to blob fields to find them fast */
1179
 
    if (!(share->blob_field= save=
1180
 
          (uint*) alloc_root(&share->mem_root,
1181
 
                             (uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1182
 
      goto err;
1183
 
    for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
1184
 
    {
1185
 
      if ((*ptr)->flags & BLOB_FLAG)
1186
 
        (*save++)= k;
1187
 
    }
1188
 
  }
1189
 
 
1190
 
  share->db_low_byte_first= true; // @todo Question this.
1191
 
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1192
 
 
1193
 
  my_bitmap_map *bitmaps;
1194
 
 
1195
 
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1196
 
                                             share->column_bitmap_size)))
1197
 
    goto err;
1198
 
  share->all_set.init(bitmaps, share->fields);
1199
 
  share->all_set.setAll();
1200
 
 
1201
 
  return (0);
1202
 
 
1203
 
err:
1204
 
  if (field_offsets)
1205
 
    free(field_offsets);
1206
 
  if (field_pack_length)
1207
 
    free(field_pack_length);
1208
 
 
1209
 
  share->error= error;
1210
 
  share->open_errno= errno;
1211
 
  share->errarg= 0;
1212
 
  hash_free(&share->name_hash);
1213
 
  share->open_table_error(error, share->open_errno, 0);
1214
 
 
1215
 
  return error;
1216
 
}
1217
 
 
1218
 
/*
1219
 
  Read table definition from a binary / text based .frm cursor
1220
 
 
1221
 
  SYNOPSIS
1222
 
  open_table_def()
1223
 
  session               Thread Cursor
1224
 
  share         Fill this with table definition
1225
 
 
1226
 
  NOTES
1227
 
    This function is called when the table definition is not cached in
1228
 
    table_def_cache
1229
 
    The data is returned in 'share', which is alloced by
1230
 
    alloc_table_share().. The code assumes that share is initialized.
1231
 
 
1232
 
  RETURN VALUES
1233
 
   0    ok
1234
 
   1    Error (see open_table_error)
1235
 
   2    Error (see open_table_error)
1236
 
   3    Wrong data in .frm cursor
1237
 
   4    Error (see open_table_error)
1238
 
   5    Error (see open_table_error: charset unavailable)
1239
 
   6    Unknown .frm version
1240
 
*/
1241
 
 
1242
 
int open_table_def(Session& session, TableIdentifier &identifier, TableShare *share)
1243
 
{
1244
 
  int error;
1245
 
  bool error_given;
1246
 
 
1247
 
  error= 1;
1248
 
  error_given= 0;
1249
 
 
1250
 
  message::Table table;
1251
 
 
1252
 
  error= plugin::StorageEngine::getTableDefinition(session, identifier, table);
1253
 
 
1254
 
  if (error != EEXIST)
1255
 
  {
1256
 
    if (error > 0)
1257
 
    {
1258
 
      errno= error;
1259
 
      error= 1;
1260
 
    }
1261
 
    else
1262
 
    {
1263
 
      if (not table.IsInitialized())
1264
 
      {
1265
 
        error= 4;
1266
 
      }
1267
 
    }
1268
 
    goto err_not_open;
1269
 
  }
1270
 
 
1271
 
  error= parse_table_proto(session, table, share);
1272
 
 
1273
 
  share->table_category= TABLE_CATEGORY_USER;
1274
 
 
1275
 
err_not_open:
1276
 
  if (error && !error_given)
1277
 
  {
1278
 
    share->error= error;
1279
 
    share->open_table_error(error, (share->open_errno= errno), 0);
1280
 
  }
1281
 
 
1282
 
  return(error);
1283
 
}
1284
 
 
1285
 
 
1286
 
/*
1287
 
  Open a table based on a TableShare
1288
 
 
1289
 
  SYNOPSIS
1290
 
    open_table_from_share()
1291
 
    session                     Thread Cursor
1292
 
    share               Table definition
1293
 
    alias               Alias for table
1294
 
    db_stat             open flags (for example HA_OPEN_KEYFILE|
1295
 
                        HA_OPEN_RNDFILE..) can be 0 (example in
1296
 
                        ha_example_table)
1297
 
    ha_open_flags       HA_OPEN_ABORT_IF_LOCKED etc..
1298
 
    outparam            result table
1299
 
 
1300
 
  RETURN VALUES
1301
 
   0    ok
1302
 
   1    Error (see open_table_error)
1303
 
   2    Error (see open_table_error)
1304
 
   3    Wrong data in .frm cursor
1305
 
   4    Error (see open_table_error)
1306
 
   5    Error (see open_table_error: charset unavailable)
1307
 
   7    Table definition has changed in engine
1308
 
*/
1309
 
 
1310
 
int open_table_from_share(Session *session, TableShare *share, const char *alias,
1311
 
                          uint32_t db_stat, uint32_t ha_open_flags,
1312
 
                          Table *outparam)
1313
 
{
1314
 
  int error;
1315
 
  uint32_t records, i, bitmap_size;
1316
 
  bool error_reported= false;
1317
 
  unsigned char *record, *bitmaps;
1318
 
  Field **field_ptr;
1319
 
 
1320
 
  /* Parsing of partitioning information from .frm needs session->lex set up. */
1321
 
  assert(session->lex->is_lex_started);
1322
 
 
1323
 
  error= 1;
1324
 
  outparam->resetTable(session, share, db_stat);
1325
 
 
1326
 
 
1327
 
  if (not (outparam->alias= strdup(alias)))
1328
 
    goto err;
1329
 
 
1330
 
  /* Allocate Cursor */
1331
 
  if (not (outparam->cursor= share->db_type()->getCursor(*share, &outparam->mem_root)))
1332
 
    goto err;
1333
 
 
1334
 
  error= 4;
1335
 
  records= 0;
1336
 
  if ((db_stat & HA_OPEN_KEYFILE))
1337
 
    records=1;
1338
 
 
1339
 
  records++;
1340
 
 
1341
 
  if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1342
 
                                   share->rec_buff_length * records)))
1343
 
    goto err;
1344
 
 
1345
 
  if (records == 0)
1346
 
  {
1347
 
    /* We are probably in hard repair, and the buffers should not be used */
1348
 
    outparam->record[0]= outparam->record[1]= share->default_values;
1349
 
  }
1350
 
  else
1351
 
  {
1352
 
    outparam->record[0]= record;
1353
 
    if (records > 1)
1354
 
      outparam->record[1]= record+ share->rec_buff_length;
1355
 
    else
1356
 
      outparam->record[1]= outparam->record[0];   // Safety
1357
 
  }
1358
 
 
1359
 
#ifdef HAVE_purify
1360
 
  /*
1361
 
    We need this because when we read var-length rows, we are not updating
1362
 
    bytes after end of varchar
1363
 
  */
1364
 
  if (records > 1)
1365
 
  {
1366
 
    memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1367
 
    memcpy(outparam->record[1], share->default_values, share->null_bytes);
1368
 
    if (records > 2)
1369
 
      memcpy(outparam->record[1], share->default_values,
1370
 
             share->rec_buff_length);
1371
 
  }
1372
 
#endif
1373
 
 
1374
 
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1375
 
                                          (uint32_t) ((share->fields+1)*
1376
 
                                                  sizeof(Field*)))))
1377
 
    goto err;
1378
 
 
1379
 
  outparam->field= field_ptr;
1380
 
 
1381
 
  record= (unsigned char*) outparam->record[0]-1;       /* Fieldstart = 1 */
1382
 
 
1383
 
  outparam->null_flags= (unsigned char*) record+1;
1384
 
 
1385
 
  /* Setup copy of fields from share, but use the right alias and record */
1386
 
  for (i= 0 ; i < share->fields; i++, field_ptr++)
1387
 
  {
1388
 
    if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1389
 
      goto err;
1390
 
  }
1391
 
  (*field_ptr)= 0;                              // End marker
1392
 
 
1393
 
  if (share->found_next_number_field)
1394
 
    outparam->found_next_number_field=
1395
 
      outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1396
 
  if (share->timestamp_field)
1397
 
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1398
 
 
1399
 
 
1400
 
  /* Fix key->name and key_part->field */
1401
 
  if (share->key_parts)
1402
 
  {
1403
 
    KEY *key_info, *key_info_end;
1404
 
    KEY_PART_INFO *key_part;
1405
 
    uint32_t n_length;
1406
 
    n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1407
 
    if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1408
 
      goto err;
1409
 
    outparam->key_info= key_info;
1410
 
    key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1411
 
 
1412
 
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1413
 
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1414
 
                                                   share->key_parts));
1415
 
 
1416
 
    for (key_info_end= key_info + share->keys ;
1417
 
         key_info < key_info_end ;
1418
 
         key_info++)
1419
 
    {
1420
 
      KEY_PART_INFO *key_part_end;
1421
 
 
1422
 
      key_info->table= outparam;
1423
 
      key_info->key_part= key_part;
1424
 
 
1425
 
      for (key_part_end= key_part+ key_info->key_parts ;
1426
 
           key_part < key_part_end ;
1427
 
           key_part++)
1428
 
      {
1429
 
        Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1430
 
 
1431
 
        if (field->key_length() != key_part->length &&
1432
 
            !(field->flags & BLOB_FLAG))
1433
 
        {
1434
 
          /*
1435
 
            We are using only a prefix of the column as a key:
1436
 
            Create a new field for the key part that matches the index
1437
 
          */
1438
 
          field= key_part->field=field->new_field(&outparam->mem_root,
1439
 
                                                  outparam, 0);
1440
 
          field->field_length= key_part->length;
1441
 
        }
1442
 
      }
1443
 
    }
1444
 
  }
1445
 
 
1446
 
  /* Allocate bitmaps */
1447
 
 
1448
 
  bitmap_size= share->column_bitmap_size;
1449
 
  if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1450
 
    goto err;
1451
 
  outparam->def_read_set.init((my_bitmap_map*) bitmaps, share->fields);
1452
 
  outparam->def_write_set.init((my_bitmap_map*) (bitmaps+bitmap_size), share->fields);
1453
 
  outparam->tmp_set.init((my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields);
1454
 
  outparam->default_column_bitmaps();
1455
 
 
1456
 
  /* The table struct is now initialized;  Open the table */
1457
 
  error= 2;
1458
 
  if (db_stat)
1459
 
  {
1460
 
    int ha_err;
1461
 
    if ((ha_err= (outparam->cursor->
1462
 
                  ha_open(outparam, share->normalized_path.str,
1463
 
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1464
 
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1465
 
                           (db_stat & HA_WAIT_IF_LOCKED) ?  HA_OPEN_WAIT_IF_LOCKED :
1466
 
                           (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1467
 
                          HA_OPEN_ABORT_IF_LOCKED :
1468
 
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1469
 
    {
1470
 
      switch (ha_err)
1471
 
      {
1472
 
        case HA_ERR_NO_SUCH_TABLE:
1473
 
          /*
1474
 
            The table did not exists in storage engine, use same error message
1475
 
            as if the .frm cursor didn't exist
1476
 
          */
1477
 
          error= 1;
1478
 
          errno= ENOENT;
1479
 
          break;
1480
 
        case EMFILE:
1481
 
          /*
1482
 
            Too many files opened, use same error message as if the .frm
1483
 
            cursor can't open
1484
 
           */
1485
 
          error= 1;
1486
 
          errno= EMFILE;
1487
 
          break;
1488
 
        default:
1489
 
          outparam->print_error(ha_err, MYF(0));
1490
 
          error_reported= true;
1491
 
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1492
 
            error= 7;
1493
 
          break;
1494
 
      }
1495
 
      goto err;
1496
 
    }
1497
 
  }
1498
 
 
1499
 
#if defined(HAVE_purify)
1500
 
  memset(bitmaps, 0, bitmap_size*3);
1501
 
#endif
1502
 
 
1503
 
  return 0;
1504
 
 
1505
 
 err:
1506
 
  if (!error_reported)
1507
 
    share->open_table_error(error, errno, 0);
1508
 
  delete outparam->cursor;
1509
 
  outparam->cursor= 0;                          // For easier error checking
1510
 
  outparam->db_stat= 0;
1511
 
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on zeroed root
1512
 
  free((char*) outparam->alias);
1513
 
  return (error);
1514
 
}
1515
 
 
1516
 
bool Table::fill_item_list(List<Item> *item_list) const
1517
 
{
1518
 
  /*
1519
 
    All Item_field's created using a direct pointer to a field
1520
 
    are fixed in Item_field constructor.
1521
 
  */
1522
 
  for (Field **ptr= field; *ptr; ptr++)
1523
 
  {
1524
 
    Item_field *item= new Item_field(*ptr);
1525
 
    if (!item || item_list->push_back(item))
1526
 
      return true;
1527
 
  }
1528
 
  return false;
1529
 
}
1530
 
 
1531
 
int Table::closefrm(bool free_share)
 
77
// @note this should all be the destructor
 
78
int Table::delete_table(bool free_share)
1532
79
{
1533
80
  int error= 0;
1534
81
 
1535
82
  if (db_stat)
1536
83
    error= cursor->close();
1537
 
  free((char*) alias);
1538
 
  alias= NULL;
 
84
  _alias.clear();
1539
85
  if (field)
1540
86
  {
1541
87
    for (Field **ptr=field ; *ptr ; ptr++)
 
88
    {
1542
89
      delete *ptr;
 
90
    }
1543
91
    field= 0;
1544
92
  }
1545
93
  delete cursor;
1546
94
  cursor= 0;                            /* For easier errorchecking */
 
95
 
1547
96
  if (free_share)
1548
97
  {
1549
 
    if (s->tmp_table == message::Table::STANDARD)
1550
 
      TableShare::release(s);
1551
 
    else
1552
 
      s->free_table_share();
 
98
    release();
1553
99
  }
1554
 
  free_root(&mem_root, MYF(0));
1555
100
 
1556
101
  return error;
1557
102
}
1558
103
 
 
104
Table::~Table()
 
105
{
 
106
  mem_root.free_root(MYF(0));
 
107
}
 
108
 
1559
109
 
1560
110
void Table::resetTable(Session *session,
1561
111
                       TableShare *share,
1562
112
                       uint32_t db_stat_arg)
1563
113
{
1564
 
  s= share;
 
114
  setShare(share);
1565
115
  field= NULL;
1566
116
 
1567
117
  cursor= NULL;
1578
128
  record[0]= (unsigned char *) NULL;
1579
129
  record[1]= (unsigned char *) NULL;
1580
130
 
1581
 
  insert_values= NULL;
 
131
  insert_values.clear();
1582
132
  key_info= NULL;
1583
133
  next_number_field= NULL;
1584
134
  found_next_number_field= NULL;
1586
136
 
1587
137
  pos_in_table_list= NULL;
1588
138
  group= NULL;
1589
 
  alias= NULL;
 
139
  _alias.clear();
1590
140
  null_flags= NULL;
1591
141
 
1592
142
  lock_position= 0;
1640
190
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
1641
191
 
1642
192
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1643
 
  memset(&sort, 0, sizeof(filesort_info_st));
1644
193
}
1645
194
 
1646
195
 
1653
202
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
1654
203
       ptr != end ;
1655
204
       ptr++)
1656
 
    ((Field_blob*) table->field[*ptr])->free();
 
205
  {
 
206
    ((Field_blob*) table->getField(*ptr))->free();
 
207
  }
1657
208
}
1658
209
 
1659
210
 
1660
 
        /* error message when opening a form cursor */
1661
 
 
1662
 
void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
1663
 
{
1664
 
  int err_no;
1665
 
  char buff[FN_REFLEN];
1666
 
  myf errortype= ME_ERROR+ME_WAITTANG;
1667
 
 
1668
 
  switch (pass_error) {
1669
 
  case 7:
1670
 
  case 1:
1671
 
    if (db_errno == ENOENT)
1672
 
      my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str);
1673
 
    else
1674
 
    {
1675
 
      snprintf(buff, sizeof(buff), "%s",normalized_path.str);
1676
 
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1677
 
               errortype, buff, db_errno);
1678
 
    }
1679
 
    break;
1680
 
  case 2:
1681
 
  {
1682
 
    Cursor *cursor= 0;
1683
 
    const char *datext= "";
1684
 
 
1685
 
    if (db_type() != NULL)
1686
 
    {
1687
 
      if ((cursor= db_type()->getCursor(*this, current_session->mem_root)))
1688
 
      {
1689
 
        if (!(datext= *db_type()->bas_ext()))
1690
 
          datext= "";
1691
 
      }
1692
 
    }
1693
 
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1694
 
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1695
 
    snprintf(buff, sizeof(buff), "%s%s", normalized_path.str,datext);
1696
 
    my_error(err_no,errortype, buff, db_errno);
1697
 
    delete cursor;
1698
 
    break;
1699
 
  }
1700
 
  case 5:
1701
 
  {
1702
 
    const char *csname= get_charset_name((uint32_t) pass_errarg);
1703
 
    char tmp[10];
1704
 
    if (!csname || csname[0] =='?')
1705
 
    {
1706
 
      snprintf(tmp, sizeof(tmp), "#%d", pass_errarg);
1707
 
      csname= tmp;
1708
 
    }
1709
 
    my_printf_error(ER_UNKNOWN_COLLATION,
1710
 
                    _("Unknown collation '%s' in table '%-.64s' definition"),
1711
 
                    MYF(0), csname, table_name.str);
1712
 
    break;
1713
 
  }
1714
 
  case 6:
1715
 
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
1716
 
    my_printf_error(ER_NOT_FORM_FILE,
1717
 
                    _("Table '%-.64s' was created with a different version "
1718
 
                    "of Drizzle and cannot be read"),
1719
 
                    MYF(0), buff);
1720
 
    break;
1721
 
  case 8:
1722
 
    break;
1723
 
  default:                              /* Better wrong error than none */
1724
 
  case 4:
1725
 
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
1726
 
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1727
 
    break;
1728
 
  }
1729
 
  return;
1730
 
} /* open_table_error */
1731
 
 
1732
 
 
1733
211
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
1734
212
{
1735
 
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
 
213
  TYPELIB *result= (TYPELIB*) mem_root->alloc_root(sizeof(TYPELIB));
1736
214
  if (!result)
1737
215
    return 0;
1738
216
  result->count= strings.elements;
1739
217
  result->name= "";
1740
218
  uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
1741
219
  
1742
 
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
 
220
  if (!(result->type_names= (const char**) mem_root->alloc_root(nbytes)))
1743
221
    return 0;
1744
222
    
1745
223
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
1769
247
  return (nr);
1770
248
} /* set_zone */
1771
249
 
1772
 
        /* Adjust number to next larger disk buffer */
1773
 
 
1774
 
ulong next_io_size(register ulong pos)
1775
 
{
1776
 
  register ulong offset;
1777
 
  if ((offset= pos & (IO_SIZE-1)))
1778
 
    return pos-offset+IO_SIZE;
1779
 
  return pos;
1780
 
} /* next_io_size */
1781
 
 
1782
250
 
1783
251
/*
1784
252
  Store an SQL quoted string.
1806
274
        (mblen= my_ismbchar(default_charset_info, pos, end)))
1807
275
    {
1808
276
      res->append(pos, mblen);
1809
 
      pos+= mblen;
 
277
      pos+= mblen - 1;
1810
278
      if (pos >= end)
1811
279
        break;
1812
280
      continue;
1842
310
}
1843
311
 
1844
312
 
1845
 
/*
1846
 
  Set up column usage bitmaps for a temporary table
1847
 
 
1848
 
  IMPLEMENTATION
1849
 
    For temporary tables, we need one bitmap with all columns set and
1850
 
    a tmp_set bitmap to be used by things like filesort.
1851
 
*/
1852
 
 
1853
 
void Table::setup_tmp_table_column_bitmaps(unsigned char *bitmaps)
1854
 
{
1855
 
  uint32_t field_count= s->fields;
1856
 
 
1857
 
  this->def_read_set.init((my_bitmap_map*) bitmaps, field_count);
1858
 
  this->tmp_set.init((my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count);
1859
 
 
1860
 
  /* write_set and all_set are copies of read_set */
1861
 
  def_write_set= def_read_set;
1862
 
  s->all_set= def_read_set;
1863
 
  this->s->all_set.setAll();
1864
 
  default_column_bitmaps();
1865
 
}
1866
 
 
1867
 
 
1868
 
 
1869
 
void Table::updateCreateInfo(message::Table *table_proto)
1870
 
{
1871
 
  message::Table::TableOptions *table_options= table_proto->mutable_options();
1872
 
  table_options->set_block_size(s->block_size);
1873
 
  table_options->set_comment(s->getComment());
1874
 
}
1875
 
 
1876
313
int rename_file_ext(const char * from,const char * to,const char * ext)
1877
314
{
1878
315
  string from_s, to_s;
1885
322
}
1886
323
 
1887
324
/*
1888
 
  DESCRIPTION
1889
 
    given a buffer with a key value, and a map of keyparts
1890
 
    that are present in this value, returns the length of the value
1891
 
*/
1892
 
uint32_t calculate_key_len(Table *table, uint32_t key,
1893
 
                       const unsigned char *,
1894
 
                       key_part_map keypart_map)
1895
 
{
1896
 
  /* works only with key prefixes */
1897
 
  assert(((keypart_map + 1) & keypart_map) == 0);
1898
 
 
1899
 
  KEY *key_info= table->s->key_info+key;
1900
 
  KEY_PART_INFO *key_part= key_info->key_part;
1901
 
  KEY_PART_INFO *end_key_part= key_part + key_info->key_parts;
1902
 
  uint32_t length= 0;
1903
 
 
1904
 
  while (key_part < end_key_part && keypart_map)
1905
 
  {
1906
 
    length+= key_part->store_length;
1907
 
    keypart_map >>= 1;
1908
 
    key_part++;
1909
 
  }
1910
 
  return length;
1911
 
}
1912
 
 
1913
 
/*
1914
325
  Check if database name is valid
1915
326
 
1916
327
  SYNPOSIS
1922
333
    true ok
1923
334
*/
1924
335
 
1925
 
bool check_db_name(SchemaIdentifier &schema_identifier)
 
336
bool check_db_name(Session *session, SchemaIdentifier &schema_identifier)
1926
337
{
1927
 
  if (not plugin::Authorization::isAuthorized(current_session->getSecurityContext(), schema_identifier))
 
338
  if (not plugin::Authorization::isAuthorized(session->getSecurityContext(), schema_identifier))
1928
339
  {
1929
340
    return false;
1930
341
  }
2002
413
    bitmap_clear_all(&table->def_read_set);
2003
414
    bitmap_clear_all(&table->def_write_set);
2004
415
  */
2005
 
  def_read_set.clearAll();
2006
 
  def_write_set.clearAll();
2007
 
  column_bitmaps_set(&def_read_set, &def_write_set);
 
416
  def_read_set.reset();
 
417
  def_write_set.reset();
 
418
  column_bitmaps_set(def_read_set, def_write_set);
2008
419
}
2009
420
 
2010
421
 
2021
432
{
2022
433
 
2023
434
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
2024
 
      s->primary_key < MAX_KEY)
 
435
      getShare()->hasPrimaryKey())
2025
436
  {
2026
 
    mark_columns_used_by_index_no_reset(s->primary_key);
 
437
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
2027
438
  }
2028
439
  return;
2029
440
}
2041
452
 
2042
453
void Table::mark_columns_used_by_index(uint32_t index)
2043
454
{
2044
 
  MyBitmap *bitmap= &tmp_set;
 
455
  boost::dynamic_bitset<> *bitmap= &tmp_set;
2045
456
 
2046
457
  (void) cursor->extra(HA_EXTRA_KEYREAD);
2047
 
  bitmap->clearAll();
2048
 
  mark_columns_used_by_index_no_reset(index, bitmap);
2049
 
  column_bitmaps_set(bitmap, bitmap);
 
458
  bitmap->reset();
 
459
  mark_columns_used_by_index_no_reset(index, *bitmap);
 
460
  column_bitmaps_set(*bitmap, *bitmap);
2050
461
  return;
2051
462
}
2052
463
 
2078
489
 
2079
490
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
2080
491
{
2081
 
    mark_columns_used_by_index_no_reset(index, read_set);
 
492
    mark_columns_used_by_index_no_reset(index, *read_set);
2082
493
}
2083
494
 
 
495
 
2084
496
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
2085
 
                                                MyBitmap *bitmap)
 
497
                                                boost::dynamic_bitset<>& bitmap)
2086
498
{
2087
 
  KEY_PART_INFO *key_part= key_info[index].key_part;
2088
 
  KEY_PART_INFO *key_part_end= (key_part +
2089
 
                                key_info[index].key_parts);
2090
 
  for (;key_part != key_part_end; key_part++)
2091
 
    bitmap->setBit(key_part->fieldnr-1);
 
499
  KeyPartInfo *key_part= key_info[index].key_part;
 
500
  KeyPartInfo *key_part_end= (key_part + key_info[index].key_parts);
 
501
  for (; key_part != key_part_end; key_part++)
 
502
  {
 
503
    if (! bitmap.empty())
 
504
      bitmap.set(key_part->fieldnr-1);
 
505
  }
2092
506
}
2093
507
 
2094
508
 
2109
523
  */
2110
524
  setReadSet(found_next_number_field->field_index);
2111
525
  setWriteSet(found_next_number_field->field_index);
2112
 
  if (s->next_number_keypart)
2113
 
    mark_columns_used_by_index_no_reset(s->next_number_index);
 
526
  if (getShare()->next_number_keypart)
 
527
    mark_columns_used_by_index_no_reset(getShare()->next_number_index);
2114
528
}
2115
529
 
2116
530
 
2141
555
    be able to do an delete
2142
556
 
2143
557
  */
2144
 
  if (s->primary_key == MAX_KEY)
 
558
  if (not getShare()->hasPrimaryKey())
2145
559
  {
2146
560
    /* fallback to use all columns in the table to identify row */
2147
561
    use_all_columns();
2148
562
    return;
2149
563
  }
2150
564
  else
2151
 
    mark_columns_used_by_index_no_reset(s->primary_key);
 
565
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
2152
566
 
2153
567
  /* If we the engine wants all predicates we mark all keys */
2154
568
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
2189
603
    the primary key, the hidden primary key or all columns to be
2190
604
    able to do an update
2191
605
  */
2192
 
  if (s->primary_key == MAX_KEY)
 
606
  if (not getShare()->hasPrimaryKey())
2193
607
  {
2194
608
    /* fallback to use all columns in the table to identify row */
2195
609
    use_all_columns();
2196
610
    return;
2197
611
  }
2198
612
  else
2199
 
    mark_columns_used_by_index_no_reset(s->primary_key);
 
613
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
2200
614
 
2201
615
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
2202
616
  {
2238
652
  {
2239
653
    Field_blob* const blob= (Field_blob*) field[*ptr];
2240
654
    length+= blob->get_length((const unsigned char*)
2241
 
                              (data + blob->offset(record[0]))) +
 
655
                              (data + blob->offset(getInsertRecord()))) +
2242
656
      HA_KEY_BLOB_LENGTH;
2243
657
  }
2244
658
  return length;
2245
659
}
2246
660
 
 
661
void Table::setVariableWidth(void)
 
662
{
 
663
  assert(in_use);
 
664
  if (in_use && in_use->lex->sql_command == SQLCOM_CREATE_TABLE)
 
665
  {
 
666
    getMutableShare()->setVariableWidth();
 
667
    return;
 
668
  }
 
669
 
 
670
  assert(0); // Programming error, you can't set this on a plain old Table.
 
671
}
 
672
 
2247
673
/****************************************************************************
2248
674
 Functions for creating temporary tables.
2249
675
****************************************************************************/
2250
 
 
2251
 
 
2252
 
/* Prototypes */
2253
 
void free_tmp_table(Session *session, Table *entry);
2254
 
 
2255
676
/**
2256
677
  Create field for temporary table from given field.
2257
678
 
2286
707
  */
2287
708
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
2288
709
      (org_field->flags & BLOB_FLAG))
 
710
  {
 
711
    table->setVariableWidth();
2289
712
    new_field= new Field_varstring(convert_blob_length,
2290
713
                                   org_field->maybe_null(),
2291
 
                                   org_field->field_name, table->s,
 
714
                                   org_field->field_name,
2292
715
                                   org_field->charset());
 
716
  }
2293
717
  else
 
718
  {
2294
719
    new_field= org_field->new_field(session->mem_root, table,
2295
 
                                    table == org_field->table);
 
720
                                    table == org_field->getTable());
 
721
  }
2296
722
  if (new_field)
2297
723
  {
2298
724
    new_field->init(table);
2305
731
    if (org_field->maybe_null() || (item && item->maybe_null))
2306
732
      new_field->flags&= ~NOT_NULL_FLAG;        // Because of outer join
2307
733
    if (org_field->type() == DRIZZLE_TYPE_VARCHAR)
2308
 
      table->s->db_create_options|= HA_OPTION_PACK_RECORD;
 
734
      table->getMutableShare()->db_create_options|= HA_OPTION_PACK_RECORD;
2309
735
    else if (org_field->type() == DRIZZLE_TYPE_DOUBLE)
2310
736
      ((Field_double *) new_field)->not_fixed= true;
2311
737
  }
2343
769
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
2344
770
#define RATIO_TO_PACK_ROWS             2
2345
771
 
2346
 
static void make_internal_temporary_table_path(Session *session, char *path)
2347
 
{
2348
 
  snprintf(path, FN_REFLEN, "%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
2349
 
           session->thread_id, session->tmp_table++);
2350
 
 
2351
 
  internal::fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
2352
 
}
2353
 
 
2354
772
Table *
2355
773
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
2356
 
                 order_st *group, bool distinct, bool save_sum_fields,
 
774
                 Order *group, bool distinct, bool save_sum_fields,
2357
775
                 uint64_t select_options, ha_rows rows_limit,
2358
776
                 const char *table_alias)
2359
777
{
2360
 
  memory::Root *mem_root_save, own_root;
2361
 
  Table *table;
2362
 
  TableShare *share;
 
778
  memory::Root *mem_root_save;
2363
779
  uint  i,field_count,null_count,null_pack_length;
2364
780
  uint32_t  copy_func_count= param->func_count;
2365
781
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
2369
785
  bool  using_unique_constraint= false;
2370
786
  bool  use_packed_rows= true;
2371
787
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
2372
 
  char  *tmpname;
2373
 
  char  path[FN_REFLEN];
2374
 
  unsigned char *pos, *group_buff, *bitmaps;
 
788
  unsigned char *pos, *group_buff;
2375
789
  unsigned char *null_flags;
2376
790
  Field **reg_field, **from_field, **default_field;
2377
 
  uint32_t *blob_field;
2378
791
  CopyField *copy= 0;
2379
 
  KEY *keyinfo;
2380
 
  KEY_PART_INFO *key_part_info;
 
792
  KeyInfo *keyinfo;
 
793
  KeyPartInfo *key_part_info;
2381
794
  Item **copy_func;
2382
795
  MI_COLUMNDEF *recinfo;
2383
796
  uint32_t total_uneven_bit_length= 0;
2384
797
  bool force_copy_fields= param->force_copy_fields;
2385
798
  uint64_t max_rows= 0;
2386
799
 
2387
 
  status_var_increment(session->status_var.created_tmp_tables);
2388
 
 
2389
 
  make_internal_temporary_table_path(session, path);
 
800
  session->status_var.created_tmp_tables++;
2390
801
 
2391
802
  if (group)
2392
803
  {
2393
804
    if (! param->quick_group)
 
805
    {
2394
806
      group= 0;                                 // Can't use group key
2395
 
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
 
807
    }
 
808
    else for (Order *tmp=group ; tmp ; tmp=tmp->next)
2396
809
    {
2397
810
      /*
2398
811
        marker == 4 means two things:
2421
834
    these items are stored in the temporary table.
2422
835
  */
2423
836
  if (param->precomputed_group_by)
 
837
  {
2424
838
    copy_func_count+= param->sum_func_count;
2425
 
 
2426
 
  memory::init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
2427
 
 
2428
 
  if (!multi_alloc_root(&own_root,
2429
 
                        &table, sizeof(*table),
2430
 
                        &share, sizeof(*share),
2431
 
                        &reg_field, sizeof(Field*) * (field_count+1),
2432
 
                        &default_field, sizeof(Field*) * (field_count),
2433
 
                        &blob_field, sizeof(uint32_t)*(field_count+1),
2434
 
                        &from_field, sizeof(Field*)*field_count,
2435
 
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
2436
 
                        &param->keyinfo, sizeof(*param->keyinfo),
2437
 
                        &key_part_info,
2438
 
                        sizeof(*key_part_info)*(param->group_parts+1),
2439
 
                        &param->start_recinfo,
2440
 
                        sizeof(*param->recinfo)*(field_count*2+4),
2441
 
                        &tmpname, (uint32_t) strlen(path)+1,
2442
 
                        &group_buff, (group && ! using_unique_constraint ?
2443
 
                                      param->group_length : 0),
2444
 
                        &bitmaps, bitmap_buffer_size(field_count)*2,
2445
 
                        NULL))
 
839
  }
 
840
 
 
841
  table::Instance *table;
 
842
  table= session->getInstanceTable(); // This will not go into the tableshare cache, so no key is used.
 
843
 
 
844
  if (not table->getMemRoot()->multi_alloc_root(0,
 
845
                                                &default_field, sizeof(Field*) * (field_count),
 
846
                                                &from_field, sizeof(Field*)*field_count,
 
847
                                                &copy_func, sizeof(*copy_func)*(copy_func_count+1),
 
848
                                                &param->keyinfo, sizeof(*param->keyinfo),
 
849
                                                &key_part_info, sizeof(*key_part_info)*(param->group_parts+1),
 
850
                                                &param->start_recinfo, sizeof(*param->recinfo)*(field_count*2+4),
 
851
                                                &group_buff, (group && ! using_unique_constraint ?
 
852
                                                              param->group_length : 0),
 
853
                                                NULL))
2446
854
  {
2447
855
    return NULL;
2448
856
  }
2449
857
  /* CopyField belongs to Tmp_Table_Param, allocate it in Session mem_root */
2450
858
  if (!(param->copy_field= copy= new (session->mem_root) CopyField[field_count]))
2451
859
  {
2452
 
    free_root(&own_root, MYF(0));
2453
860
    return NULL;
2454
861
  }
2455
862
  param->items_to_copy= copy_func;
2456
 
  strcpy(tmpname,path);
2457
863
  /* make table according to fields */
2458
864
 
2459
 
  memset(table, 0, sizeof(*table));
2460
 
  memset(reg_field, 0, sizeof(Field*)*(field_count+1));
2461
865
  memset(default_field, 0, sizeof(Field*) * (field_count));
2462
866
  memset(from_field, 0, sizeof(Field*)*field_count);
2463
867
 
2464
 
  table->mem_root= own_root;
2465
868
  mem_root_save= session->mem_root;
2466
 
  session->mem_root= &table->mem_root;
 
869
  session->mem_root= table->getMemRoot();
2467
870
 
2468
 
  table->field=reg_field;
2469
 
  table->alias= table_alias;
 
871
  table->getMutableShare()->setFields(field_count+1);
 
872
  table->setFields(table->getMutableShare()->getFields(true));
 
873
  reg_field= table->getMutableShare()->getFields(true);
 
874
  table->setAlias(table_alias);
2470
875
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
2471
876
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
2472
877
  table->map=1;
2473
878
  table->copy_blobs= 1;
 
879
  assert(session);
2474
880
  table->in_use= session;
2475
881
  table->quick_keys.reset();
2476
882
  table->covering_keys.reset();
2477
883
  table->keys_in_use_for_query.reset();
2478
884
 
2479
 
  table->setShare(share);
2480
 
  share->init(tmpname, tmpname);
2481
 
  share->blob_field= blob_field;
2482
 
  share->blob_ptr_size= portable_sizeof_char_ptr;
2483
 
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
2484
 
  share->table_charset= param->table_charset;
2485
 
  share->primary_key= MAX_KEY;               // Indicate no primary key
2486
 
  share->keys_for_keyread.reset();
2487
 
  share->keys_in_use.reset();
 
885
  table->getMutableShare()->blob_field.resize(field_count+1);
 
886
  uint32_t *blob_field= &table->getMutableShare()->blob_field[0];
 
887
  table->getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
 
888
  table->getMutableShare()->db_low_byte_first=1;                // True for HEAP and MyISAM
 
889
  table->getMutableShare()->table_charset= param->table_charset;
 
890
  table->getMutableShare()->keys_for_keyread.reset();
 
891
  table->getMutableShare()->keys_in_use.reset();
2488
892
 
2489
893
  /* Calculate which type of fields we will store in the temporary table */
2490
894
 
2551
955
          }
2552
956
          session->mem_root= mem_root_save;
2553
957
          session->change_item_tree(argp, new Item_field(new_field));
2554
 
          session->mem_root= &table->mem_root;
 
958
          session->mem_root= table->getMemRoot();
2555
959
          if (!(new_field->flags & NOT_NULL_FLAG))
2556
960
          {
2557
961
            null_count++;
2626
1030
      null_count= 0;
2627
1031
    }
2628
1032
  }
2629
 
  assert(fieldnr == (uint32_t) (reg_field - table->field));
2630
 
  assert(field_count >= (uint32_t) (reg_field - table->field));
 
1033
  assert(fieldnr == (uint32_t) (reg_field - table->getFields()));
 
1034
  assert(field_count >= (uint32_t) (reg_field - table->getFields()));
2631
1035
  field_count= fieldnr;
2632
1036
  *reg_field= 0;
2633
1037
  *blob_field= 0;                               // End marker
2634
 
  share->fields= field_count;
 
1038
  table->getMutableShare()->fields= field_count;
2635
1039
 
2636
1040
  /* If result table is small; use a heap */
2637
1041
  /* future: storage engine selection can be made dynamic? */
2638
 
  if (blob_count || using_unique_constraint ||
 
1042
  if (blob_count || using_unique_constraint || 
 
1043
      (session->lex->select_lex.options & SELECT_BIG_RESULT) ||
 
1044
      (session->lex->current_select->olap == ROLLUP_TYPE) ||
2639
1045
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
2640
1046
  {
2641
 
    share->storage_engine= myisam_engine;
2642
 
    table->cursor= share->db_type()->getCursor(*share, &table->mem_root);
 
1047
    table->getMutableShare()->storage_engine= myisam_engine;
 
1048
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
2643
1049
    if (group &&
2644
1050
        (param->group_parts > table->cursor->getEngine()->max_key_parts() ||
2645
1051
         param->group_length > table->cursor->getEngine()->max_key_length()))
 
1052
    {
2646
1053
      using_unique_constraint= true;
 
1054
    }
2647
1055
  }
2648
1056
  else
2649
1057
  {
2650
 
    share->storage_engine= heap_engine;
2651
 
    table->cursor= share->db_type()->getCursor(*share, &table->mem_root);
 
1058
    table->getMutableShare()->storage_engine= heap_engine;
 
1059
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
2652
1060
  }
2653
1061
  if (! table->cursor)
2654
1062
    goto err;
2657
1065
  if (! using_unique_constraint)
2658
1066
    reclength+= group_null_items;       // null flag is stored separately
2659
1067
 
2660
 
  share->blob_fields= blob_count;
 
1068
  table->getMutableShare()->blob_fields= blob_count;
2661
1069
  if (blob_count == 0)
2662
1070
  {
2663
1071
    /* We need to ensure that first byte is not 0 for the delete link */
2676
1084
  if (blob_count || ((string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS) && (reclength / string_total_length <= RATIO_TO_PACK_ROWS || (string_total_length / string_count) >= AVG_STRING_LENGTH_TO_PACK_ROWS)))
2677
1085
    use_packed_rows= 1;
2678
1086
 
2679
 
  share->reclength= reclength;
 
1087
  table->getMutableShare()->setRecordLength(reclength);
2680
1088
  {
2681
1089
    uint32_t alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
2682
 
    share->rec_buff_length= alloc_length;
2683
 
    if (!(table->record[0]= (unsigned char*)
2684
 
                            alloc_root(&table->mem_root, alloc_length*3)))
 
1090
    table->getMutableShare()->rec_buff_length= alloc_length;
 
1091
    if (!(table->record[0]= (unsigned char*) table->alloc_root(alloc_length*2)))
 
1092
    {
2685
1093
      goto err;
2686
 
    table->record[1]= table->record[0]+alloc_length;
2687
 
    share->default_values= table->record[1]+alloc_length;
 
1094
    }
 
1095
    table->record[1]= table->getInsertRecord()+alloc_length;
 
1096
    table->getMutableShare()->resizeDefaultValues(alloc_length);
2688
1097
  }
2689
1098
  copy_func[0]= 0;                              // End marker
2690
1099
  param->func_count= copy_func - param->items_to_copy;
2691
1100
 
2692
 
  table->setup_tmp_table_column_bitmaps(bitmaps);
 
1101
  table->setup_tmp_table_column_bitmaps();
2693
1102
 
2694
1103
  recinfo=param->start_recinfo;
2695
 
  null_flags=(unsigned char*) table->record[0];
2696
 
  pos=table->record[0]+ null_pack_length;
 
1104
  null_flags=(unsigned char*) table->getInsertRecord();
 
1105
  pos=table->getInsertRecord()+ null_pack_length;
2697
1106
  if (null_pack_length)
2698
1107
  {
2699
1108
    memset(recinfo, 0, sizeof(*recinfo));
2702
1111
    recinfo++;
2703
1112
    memset(null_flags, 255, null_pack_length);  // Set null fields
2704
1113
 
2705
 
    table->null_flags= (unsigned char*) table->record[0];
2706
 
    share->null_fields= null_count+ hidden_null_count;
2707
 
    share->null_bytes= null_pack_length;
 
1114
    table->null_flags= (unsigned char*) table->getInsertRecord();
 
1115
    table->getMutableShare()->null_fields= null_count+ hidden_null_count;
 
1116
    table->getMutableShare()->null_bytes= null_pack_length;
2708
1117
  }
2709
1118
  null_count= (blob_count == 0) ? 1 : 0;
2710
1119
  hidden_field_count=param->hidden_field_count;
2711
 
  for (i= 0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
 
1120
  for (i= 0,reg_field= table->getFields(); i < field_count; i++,reg_field++,recinfo++)
2712
1121
  {
2713
1122
    Field *field= *reg_field;
2714
1123
    uint32_t length;
2755
1164
      ptrdiff_t diff;
2756
1165
      Field *orig_field= default_field[i];
2757
1166
      /* Get the value from default_values */
2758
 
      diff= (ptrdiff_t) (orig_field->table->s->default_values-
2759
 
                            orig_field->table->record[0]);
 
1167
      diff= (ptrdiff_t) (orig_field->getTable()->getDefaultValues() - orig_field->getTable()->getInsertRecord());
2760
1168
      orig_field->move_field_offset(diff);      // Points now at default_values
2761
1169
      if (orig_field->is_real_null())
2762
1170
        field->set_null();
2765
1173
        field->set_notnull();
2766
1174
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
2767
1175
      }
2768
 
      orig_field->move_field_offset(-diff);     // Back to record[0]
 
1176
      orig_field->move_field_offset(-diff);     // Back to getInsertRecord()
2769
1177
    }
2770
1178
 
2771
1179
    if (from_field[i])
2784
1192
      recinfo->type=FIELD_NORMAL;
2785
1193
    if (!--hidden_field_count)
2786
1194
      null_count=(null_count+7) & ~7;           // move to next byte
2787
 
 
2788
 
    // fix table name in field entry
2789
 
    field->table_name= &table->alias;
2790
1195
  }
2791
1196
 
2792
1197
  param->copy_field_end=copy;
2794
1199
  table->storeRecordAsDefault();        // Make empty default record
2795
1200
 
2796
1201
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
 
1202
  {
2797
1203
    max_rows= ~(uint64_t) 0;
 
1204
  }
2798
1205
  else
2799
 
    max_rows= (uint64_t) (((share->db_type() == heap_engine) ?
2800
 
                          min(session->variables.tmp_table_size,
2801
 
                              session->variables.max_heap_table_size) :
2802
 
                          session->variables.tmp_table_size) /
2803
 
                         share->reclength);
 
1206
  {
 
1207
    max_rows= (uint64_t) (((table->getMutableShare()->db_type() == heap_engine) ?
 
1208
                           min(session->variables.tmp_table_size,
 
1209
                               session->variables.max_heap_table_size) :
 
1210
                           session->variables.tmp_table_size) /
 
1211
                          table->getMutableShare()->getRecordLength());
 
1212
  }
2804
1213
 
2805
1214
  set_if_bigger(max_rows, (uint64_t)1); // For dummy start options
2806
1215
  /*
2809
1218
  */
2810
1219
  set_if_smaller(max_rows, rows_limit);
2811
1220
 
2812
 
  share->setMaxRows(max_rows);
 
1221
  table->getMutableShare()->setMaxRows(max_rows);
2813
1222
 
2814
1223
  param->end_write_records= rows_limit;
2815
1224
 
2819
1228
  {
2820
1229
    table->group=group;                         /* Table is grouped by key */
2821
1230
    param->group_buff=group_buff;
2822
 
    share->keys=1;
2823
 
    share->uniques= test(using_unique_constraint);
 
1231
    table->getMutableShare()->keys=1;
 
1232
    table->getMutableShare()->uniques= test(using_unique_constraint);
2824
1233
    table->key_info=keyinfo;
2825
1234
    keyinfo->key_part=key_part_info;
2826
1235
    keyinfo->flags=HA_NOSAME;
2829
1238
    keyinfo->rec_per_key= 0;
2830
1239
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
2831
1240
    keyinfo->name= (char*) "group_key";
2832
 
    order_st *cur_group= group;
 
1241
    Order *cur_group= group;
2833
1242
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
2834
1243
    {
2835
1244
      Field *field=(*cur_group->item)->get_tmp_table_field();
2836
1245
      bool maybe_null=(*cur_group->item)->maybe_null;
2837
1246
      key_part_info->null_bit= 0;
2838
1247
      key_part_info->field=  field;
2839
 
      key_part_info->offset= field->offset(table->record[0]);
 
1248
      key_part_info->offset= field->offset(table->getInsertRecord());
2840
1249
      key_part_info->length= (uint16_t) field->key_length();
2841
1250
      key_part_info->type=   (uint8_t) field->key_type();
2842
1251
      key_part_info->key_type= 
2864
1273
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
2865
1274
          key_part_info->null_bit=field->null_bit;
2866
1275
          key_part_info->null_offset= (uint32_t) (field->null_ptr -
2867
 
                                              (unsigned char*) table->record[0]);
 
1276
                                              (unsigned char*) table->getInsertRecord());
2868
1277
          cur_group->buff++;                        // Pointer to field data
2869
1278
          group_buff++;                         // Skipp null flag
2870
1279
        }
2891
1300
        indexes on blobs with arbitrary length. Such indexes cannot be
2892
1301
        used for lookups.
2893
1302
      */
2894
 
      share->uniques= 1;
 
1303
      table->getMutableShare()->uniques= 1;
2895
1304
    }
2896
1305
    null_pack_length-=hidden_null_pack_length;
2897
1306
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
2898
 
                         (share->uniques ? test(null_pack_length) : 0));
 
1307
                         (table->getMutableShare()->uniques ? test(null_pack_length) : 0));
2899
1308
    table->distinct= 1;
2900
 
    share->keys= 1;
2901
 
    if (!(key_part_info= (KEY_PART_INFO*)
2902
 
          alloc_root(&table->mem_root,
2903
 
                     keyinfo->key_parts * sizeof(KEY_PART_INFO))))
 
1309
    table->getMutableShare()->keys= 1;
 
1310
    if (!(key_part_info= (KeyPartInfo*)
 
1311
         table->alloc_root(keyinfo->key_parts * sizeof(KeyPartInfo))))
2904
1312
      goto err;
2905
 
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KEY_PART_INFO));
 
1313
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KeyPartInfo));
2906
1314
    table->key_info=keyinfo;
2907
1315
    keyinfo->key_part=key_part_info;
2908
1316
    keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
2916
1324
      blobs can distinguish NULL from 0. This extra field is not needed
2917
1325
      when we do not use UNIQUE indexes for blobs.
2918
1326
    */
2919
 
    if (null_pack_length && share->uniques)
 
1327
    if (null_pack_length && table->getMutableShare()->uniques)
2920
1328
    {
2921
1329
      key_part_info->null_bit= 0;
2922
1330
      key_part_info->offset=hidden_null_pack_length;
2923
1331
      key_part_info->length=null_pack_length;
2924
 
      key_part_info->field= new Field_varstring(table->record[0],
 
1332
      table->setVariableWidth();
 
1333
      key_part_info->field= new Field_varstring(table->getInsertRecord(),
2925
1334
                                                (uint32_t) key_part_info->length,
2926
1335
                                                0,
2927
1336
                                                (unsigned char*) 0,
2928
1337
                                                (uint32_t) 0,
2929
1338
                                                NULL,
2930
 
                                                table->s,
2931
1339
                                                &my_charset_bin);
2932
1340
      if (!key_part_info->field)
2933
1341
        goto err;
2937
1345
      key_part_info++;
2938
1346
    }
2939
1347
    /* Create a distinct key over the columns we are going to return */
2940
 
    for (i=param->hidden_field_count, reg_field=table->field + i ;
 
1348
    for (i=param->hidden_field_count, reg_field=table->getFields() + i ;
2941
1349
         i < field_count;
2942
1350
         i++, reg_field++, key_part_info++)
2943
1351
    {
2944
1352
      key_part_info->null_bit= 0;
2945
1353
      key_part_info->field=    *reg_field;
2946
 
      key_part_info->offset=   (*reg_field)->offset(table->record[0]);
 
1354
      key_part_info->offset=   (*reg_field)->offset(table->getInsertRecord());
2947
1355
      key_part_info->length=   (uint16_t) (*reg_field)->pack_length();
2948
 
      /* TODO:
2949
 
        The below method of computing the key format length of the
 
1356
      /* @todo The below method of computing the key format length of the
2950
1357
        key part is a copy/paste from optimizer/range.cc, and table.cc.
2951
1358
        This should be factored out, e.g. as a method of Field.
2952
1359
        In addition it is not clear if any of the Field::*_length
2972
1379
 
2973
1380
  if (session->is_fatal_error)                          // If end of memory
2974
1381
    goto err;
2975
 
  share->db_record_offset= 1;
2976
 
  if (share->db_type() == myisam_engine)
 
1382
  table->getMutableShare()->db_record_offset= 1;
 
1383
  if (table->getShare()->db_type() == myisam_engine)
2977
1384
  {
2978
1385
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
2979
1386
                                       &param->recinfo, select_options))
2980
1387
      goto err;
2981
1388
  }
 
1389
  assert(table->in_use);
2982
1390
  if (table->open_tmp_table())
2983
1391
    goto err;
2984
1392
 
2988
1396
 
2989
1397
err:
2990
1398
  session->mem_root= mem_root_save;
2991
 
  table->free_tmp_table(session);
 
1399
  table= NULL;
 
1400
 
2992
1401
  return NULL;
2993
1402
}
2994
1403
 
2995
1404
/****************************************************************************/
2996
1405
 
2997
 
/**
2998
 
  Create a reduced Table object with properly set up Field list from a
2999
 
  list of field definitions.
3000
 
 
3001
 
    The created table doesn't have a table Cursor associated with
3002
 
    it, has no keys, no group/distinct, no copy_funcs array.
3003
 
    The sole purpose of this Table object is to use the power of Field
3004
 
    class to read/write data to/from table->record[0]. Then one can store
3005
 
    the record in any container (RB tree, hash, etc).
3006
 
    The table is created in Session mem_root, so are the table's fields.
3007
 
    Consequently, if you don't BLOB fields, you don't need to free it.
3008
 
 
3009
 
  @param session         connection handle
3010
 
  @param field_list  list of column definitions
3011
 
 
3012
 
  @return
3013
 
    0 if out of memory, Table object in case of success
3014
 
*/
3015
 
 
3016
 
Table *create_virtual_tmp_table(Session *session, List<CreateField> &field_list)
3017
 
{
3018
 
  uint32_t field_count= field_list.elements;
3019
 
  uint32_t blob_count= 0;
3020
 
  Field **field;
3021
 
  CreateField *cdef;                           /* column definition */
3022
 
  uint32_t record_length= 0;
3023
 
  uint32_t null_count= 0;                 /* number of columns which may be null */
3024
 
  uint32_t null_pack_length;              /* NULL representation array length */
3025
 
  uint32_t *blob_field;
3026
 
  unsigned char *bitmaps;
3027
 
  Table *table;
3028
 
  TableShare *share;
3029
 
 
3030
 
  if (!multi_alloc_root(session->mem_root,
3031
 
                        &table, sizeof(*table),
3032
 
                        &share, sizeof(*share),
3033
 
                        &field, (field_count + 1) * sizeof(Field*),
3034
 
                        &blob_field, (field_count+1) *sizeof(uint32_t),
3035
 
                        &bitmaps, bitmap_buffer_size(field_count)*2,
3036
 
                        NULL))
3037
 
    return NULL;
3038
 
 
3039
 
  memset(table, 0, sizeof(*table));
3040
 
  memset(share, 0, sizeof(*share));
3041
 
  table->field= field;
3042
 
  table->s= share;
3043
 
  share->blob_field= blob_field;
3044
 
  share->fields= field_count;
3045
 
  share->blob_ptr_size= portable_sizeof_char_ptr;
3046
 
  table->setup_tmp_table_column_bitmaps(bitmaps);
3047
 
 
3048
 
  /* Create all fields and calculate the total length of record */
3049
 
  List_iterator_fast<CreateField> it(field_list);
3050
 
  while ((cdef= it++))
3051
 
  {
3052
 
    *field= make_field(share,
3053
 
                       NULL,
3054
 
                       0,
3055
 
                       cdef->length,
3056
 
                       (cdef->flags & NOT_NULL_FLAG) ? false : true,
3057
 
                       (unsigned char *) ((cdef->flags & NOT_NULL_FLAG) ? 0 : ""),
3058
 
                       (cdef->flags & NOT_NULL_FLAG) ? 0 : 1,
3059
 
                       cdef->decimals,
3060
 
                       cdef->sql_type,
3061
 
                       cdef->charset,
3062
 
                       cdef->unireg_check,
3063
 
                       cdef->interval,
3064
 
                       cdef->field_name);
3065
 
    if (!*field)
3066
 
      goto error;
3067
 
    (*field)->init(table);
3068
 
    record_length+= (*field)->pack_length();
3069
 
    if (! ((*field)->flags & NOT_NULL_FLAG))
3070
 
      null_count++;
3071
 
 
3072
 
    if ((*field)->flags & BLOB_FLAG)
3073
 
      share->blob_field[blob_count++]= (uint32_t) (field - table->field);
3074
 
 
3075
 
    field++;
3076
 
  }
3077
 
  *field= NULL;                             /* mark the end of the list */
3078
 
  share->blob_field[blob_count]= 0;            /* mark the end of the list */
3079
 
  share->blob_fields= blob_count;
3080
 
 
3081
 
  null_pack_length= (null_count + 7)/8;
3082
 
  share->reclength= record_length + null_pack_length;
3083
 
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
3084
 
  table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
3085
 
  if (!table->record[0])
3086
 
    goto error;
3087
 
 
3088
 
  if (null_pack_length)
3089
 
  {
3090
 
    table->null_flags= (unsigned char*) table->record[0];
3091
 
    share->null_fields= null_count;
3092
 
    share->null_bytes= null_pack_length;
3093
 
  }
3094
 
 
3095
 
  table->in_use= session;           /* field->reset() may access table->in_use */
3096
 
  {
3097
 
    /* Set up field pointers */
3098
 
    unsigned char *null_pos= table->record[0];
3099
 
    unsigned char *field_pos= null_pos + share->null_bytes;
3100
 
    uint32_t null_bit= 1;
3101
 
 
3102
 
    for (field= table->field; *field; ++field)
3103
 
    {
3104
 
      Field *cur_field= *field;
3105
 
      if ((cur_field->flags & NOT_NULL_FLAG))
3106
 
        cur_field->move_field(field_pos);
3107
 
      else
3108
 
      {
3109
 
        cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
3110
 
        null_bit<<= 1;
3111
 
        if (null_bit == (1 << 8))
3112
 
        {
3113
 
          ++null_pos;
3114
 
          null_bit= 1;
3115
 
        }
3116
 
      }
3117
 
      cur_field->reset();
3118
 
 
3119
 
      field_pos+= cur_field->pack_length();
3120
 
    }
3121
 
  }
3122
 
  return table;
3123
 
error:
3124
 
  for (field= table->field; *field; ++field)
3125
 
    delete *field;                         /* just invokes field destructor */
3126
 
  return 0;
3127
 
}
3128
 
 
3129
 
bool Table::open_tmp_table()
3130
 
{
3131
 
  int error;
3132
 
  if ((error=cursor->ha_open(this, s->table_name.str,O_RDWR,
3133
 
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
3134
 
  {
3135
 
    print_error(error, MYF(0));
3136
 
    db_stat= 0;
3137
 
    return true;
3138
 
  }
3139
 
  (void) cursor->extra(HA_EXTRA_QUICK);         /* Faster */
3140
 
  return false;
3141
 
}
3142
 
 
3143
 
 
3144
 
/*
3145
 
  Create MyISAM temporary table
3146
 
 
3147
 
  SYNOPSIS
3148
 
    create_myisam_tmp_table()
3149
 
      keyinfo         Description of the index (there is always one index)
3150
 
      start_recinfo   MyISAM's column descriptions
3151
 
      recinfo INOUT   End of MyISAM's column descriptions
3152
 
      options         Option bits
3153
 
 
3154
 
  DESCRIPTION
3155
 
    Create a MyISAM temporary table according to passed description. The is
3156
 
    assumed to have one unique index or constraint.
3157
 
 
3158
 
    The passed array or MI_COLUMNDEF structures must have this form:
3159
 
 
3160
 
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
3161
 
         when there are many nullable columns)
3162
 
      2. Table columns
3163
 
      3. One free MI_COLUMNDEF element (*recinfo points here)
3164
 
 
3165
 
    This function may use the free element to create hash column for unique
3166
 
    constraint.
3167
 
 
3168
 
   RETURN
3169
 
     false - OK
3170
 
     true  - Error
3171
 
*/
3172
 
 
3173
 
bool Table::create_myisam_tmp_table(KEY *keyinfo,
3174
 
                                    MI_COLUMNDEF *start_recinfo,
3175
 
                                    MI_COLUMNDEF **recinfo,
3176
 
                                    uint64_t options)
3177
 
{
3178
 
  int error;
3179
 
  MI_KEYDEF keydef;
3180
 
  MI_UNIQUEDEF uniquedef;
3181
 
  TableShare *share= s;
3182
 
 
3183
 
  if (share->keys)
3184
 
  {                                             // Get keys for ni_create
3185
 
    bool using_unique_constraint= false;
3186
 
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
3187
 
                                            sizeof(*seg) * keyinfo->key_parts);
3188
 
    if (!seg)
3189
 
      goto err;
3190
 
 
3191
 
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
3192
 
    if (keyinfo->key_length >= cursor->getEngine()->max_key_length() ||
3193
 
        keyinfo->key_parts > cursor->getEngine()->max_key_parts() ||
3194
 
        share->uniques)
3195
 
    {
3196
 
      /* Can't create a key; Make a unique constraint instead of a key */
3197
 
      share->keys=    0;
3198
 
      share->uniques= 1;
3199
 
      using_unique_constraint= true;
3200
 
      memset(&uniquedef, 0, sizeof(uniquedef));
3201
 
      uniquedef.keysegs=keyinfo->key_parts;
3202
 
      uniquedef.seg=seg;
3203
 
      uniquedef.null_are_equal=1;
3204
 
 
3205
 
      /* Create extra column for hash value */
3206
 
      memset(*recinfo, 0, sizeof(**recinfo));
3207
 
      (*recinfo)->type= FIELD_CHECK;
3208
 
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
3209
 
      (*recinfo)++;
3210
 
      share->reclength+=MI_UNIQUE_HASH_LENGTH;
3211
 
    }
3212
 
    else
3213
 
    {
3214
 
      /* Create an unique key */
3215
 
      memset(&keydef, 0, sizeof(keydef));
3216
 
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
3217
 
      keydef.keysegs=  keyinfo->key_parts;
3218
 
      keydef.seg= seg;
3219
 
    }
3220
 
    for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
3221
 
    {
3222
 
      Field *key_field=keyinfo->key_part[i].field;
3223
 
      seg->flag=     0;
3224
 
      seg->language= key_field->charset()->number;
3225
 
      seg->length=   keyinfo->key_part[i].length;
3226
 
      seg->start=    keyinfo->key_part[i].offset;
3227
 
      if (key_field->flags & BLOB_FLAG)
3228
 
      {
3229
 
        seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
3230
 
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
3231
 
        seg->bit_start= (uint8_t)(key_field->pack_length()
3232
 
                                  - share->blob_ptr_size);
3233
 
        seg->flag= HA_BLOB_PART;
3234
 
        seg->length= 0;                 // Whole blob in unique constraint
3235
 
      }
3236
 
      else
3237
 
      {
3238
 
        seg->type= keyinfo->key_part[i].type;
3239
 
      }
3240
 
      if (!(key_field->flags & NOT_NULL_FLAG))
3241
 
      {
3242
 
        seg->null_bit= key_field->null_bit;
3243
 
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
3244
 
        /*
3245
 
          We are using a GROUP BY on something that contains NULL
3246
 
          In this case we have to tell MyISAM that two NULL should
3247
 
          on INSERT be regarded at the same value
3248
 
        */
3249
 
        if (! using_unique_constraint)
3250
 
          keydef.flag|= HA_NULL_ARE_EQUAL;
3251
 
      }
3252
 
    }
3253
 
  }
3254
 
  MI_CREATE_INFO create_info;
3255
 
  memset(&create_info, 0, sizeof(create_info));
3256
 
 
3257
 
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
3258
 
      OPTION_BIG_TABLES)
3259
 
    create_info.data_file_length= ~(uint64_t) 0;
3260
 
 
3261
 
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
3262
 
                       (uint32_t) (*recinfo-start_recinfo),
3263
 
                       start_recinfo,
3264
 
                       share->uniques, &uniquedef,
3265
 
                       &create_info,
3266
 
                       HA_CREATE_TMP_TABLE)))
3267
 
  {
3268
 
    print_error(error, MYF(0));
3269
 
    db_stat= 0;
3270
 
    goto err;
3271
 
  }
3272
 
  status_var_increment(in_use->status_var.created_tmp_disk_tables);
3273
 
  share->db_record_offset= 1;
3274
 
  return false;
3275
 
 err:
3276
 
  return true;
3277
 
}
3278
 
 
3279
 
 
3280
 
void Table::free_tmp_table(Session *session)
3281
 
{
3282
 
  memory::Root own_root= mem_root;
3283
 
  const char *save_proc_info;
3284
 
 
3285
 
  save_proc_info=session->get_proc_info();
3286
 
  session->set_proc_info("removing tmp table");
3287
 
 
3288
 
  // Release latches since this can take a long time
3289
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
3290
 
 
3291
 
  if (cursor)
3292
 
  {
3293
 
    if (db_stat)
3294
 
      cursor->closeMarkForDelete(s->table_name.str);
3295
 
 
3296
 
    TableIdentifier identifier(s->getSchemaName(), s->table_name.str, s->table_name.str);
3297
 
    s->db_type()->doDropTable(*session, identifier);
3298
 
 
3299
 
    delete cursor;
3300
 
  }
3301
 
 
3302
 
  /* free blobs */
3303
 
  for (Field **ptr= field ; *ptr ; ptr++)
3304
 
    (*ptr)->free();
3305
 
  free_io_cache();
3306
 
 
3307
 
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
3308
 
  session->set_proc_info(save_proc_info);
3309
 
}
3310
 
 
3311
 
/**
3312
 
  If a HEAP table gets full, create a MyISAM table and copy all rows
3313
 
  to this.
3314
 
*/
3315
 
 
3316
 
bool create_myisam_from_heap(Session *session, Table *table,
3317
 
                             MI_COLUMNDEF *start_recinfo,
3318
 
                             MI_COLUMNDEF **recinfo,
3319
 
                             int error, bool ignore_last_dupp_key_error)
3320
 
{
3321
 
  Table new_table;
3322
 
  TableShare share;
3323
 
  const char *save_proc_info;
3324
 
  int write_err;
3325
 
 
3326
 
  if (table->s->db_type() != heap_engine ||
3327
 
      error != HA_ERR_RECORD_FILE_FULL)
3328
 
  {
3329
 
    table->print_error(error, MYF(0));
3330
 
    return true;
3331
 
  }
3332
 
 
3333
 
  // Release latches since this can take a long time
3334
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
3335
 
 
3336
 
  new_table= *table;
3337
 
  share= *table->s;
3338
 
  new_table.s= &share;
3339
 
  new_table.s->storage_engine= myisam_engine;
3340
 
  if (not (new_table.cursor= new_table.s->db_type()->getCursor(share, &new_table.mem_root)))
3341
 
    return true;                                // End of memory
3342
 
 
3343
 
  save_proc_info=session->get_proc_info();
3344
 
  session->set_proc_info("converting HEAP to MyISAM");
3345
 
 
3346
 
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
3347
 
                                        recinfo, session->lex->select_lex.options |
3348
 
                                        session->options))
3349
 
    goto err2;
3350
 
  if (new_table.open_tmp_table())
3351
 
    goto err1;
3352
 
  if (table->cursor->indexes_are_disabled())
3353
 
    new_table.cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL);
3354
 
  table->cursor->ha_index_or_rnd_end();
3355
 
  table->cursor->ha_rnd_init(1);
3356
 
  if (table->no_rows)
3357
 
  {
3358
 
    new_table.cursor->extra(HA_EXTRA_NO_ROWS);
3359
 
    new_table.no_rows=1;
3360
 
  }
3361
 
 
3362
 
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
3363
 
  new_table.cursor->extra(HA_EXTRA_WRITE_CACHE);
3364
 
 
3365
 
  /*
3366
 
    copy all old rows from heap table to MyISAM table
3367
 
    This is the only code that uses record[1] to read/write but this
3368
 
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
3369
 
  */
3370
 
  while (!table->cursor->rnd_next(new_table.record[1]))
3371
 
  {
3372
 
    write_err= new_table.cursor->ha_write_row(new_table.record[1]);
3373
 
    if (write_err)
3374
 
      goto err;
3375
 
  }
3376
 
  /* copy row that filled HEAP table */
3377
 
  if ((write_err=new_table.cursor->ha_write_row(table->record[0])))
3378
 
  {
3379
 
    if (new_table.cursor->is_fatal_error(write_err, HA_CHECK_DUP) ||
3380
 
        !ignore_last_dupp_key_error)
3381
 
      goto err;
3382
 
  }
3383
 
 
3384
 
  /* remove heap table and change to use myisam table */
3385
 
  (void) table->cursor->ha_rnd_end();
3386
 
  (void) table->cursor->close();                  // This deletes the table !
3387
 
  delete table->cursor;
3388
 
  table->cursor= NULL;
3389
 
  new_table.s= table->s;                       // Keep old share
3390
 
  *table= new_table;
3391
 
  *table->s= share;
3392
 
 
3393
 
  table->cursor->change_table_ptr(table, table->s);
3394
 
  table->use_all_columns();
3395
 
  if (save_proc_info)
3396
 
  {
3397
 
    const char *new_proc_info=
3398
 
      (!strcmp(save_proc_info,"Copying to tmp table") ?
3399
 
      "Copying to tmp table on disk" : save_proc_info);
3400
 
    session->set_proc_info(new_proc_info);
3401
 
  }
3402
 
  return false;
3403
 
 
3404
 
 err:
3405
 
  table->print_error(write_err, MYF(0));
3406
 
  (void) table->cursor->ha_rnd_end();
3407
 
  (void) new_table.cursor->close();
3408
 
 
3409
 
 err1:
3410
 
  {
3411
 
    TableIdentifier identifier(new_table.s->getSchemaName(), new_table.s->table_name.str, new_table.s->table_name.str);
3412
 
    new_table.s->db_type()->doDropTable(*session, identifier);
3413
 
  }
3414
 
 
3415
 
 err2:
3416
 
  delete new_table.cursor;
3417
 
  session->set_proc_info(save_proc_info);
3418
 
  table->mem_root= new_table.mem_root;
3419
 
  return true;
3420
 
}
3421
 
 
3422
 
my_bitmap_map *Table::use_all_columns(MyBitmap *bitmap)
3423
 
{
3424
 
  my_bitmap_map *old= bitmap->getBitmap();
3425
 
  bitmap->setBitmap(s->all_set.getBitmap());
 
1406
void Table::column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
 
1407
                               boost::dynamic_bitset<>& write_set_arg)
 
1408
{
 
1409
  read_set= &read_set_arg;
 
1410
  write_set= &write_set_arg;
 
1411
}
 
1412
 
 
1413
 
 
1414
const boost::dynamic_bitset<> Table::use_all_columns(boost::dynamic_bitset<>& in_map)
 
1415
{
 
1416
  const boost::dynamic_bitset<> old= in_map;
 
1417
  in_map= getShare()->all_set;
3426
1418
  return old;
3427
1419
}
3428
1420
 
3429
 
void Table::restore_column_map(my_bitmap_map *old)
 
1421
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
3430
1422
{
3431
 
  read_set->setBitmap(old);
 
1423
  for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
 
1424
  {
 
1425
    if (old.test(i))
 
1426
    {
 
1427
      read_set->set(i);
 
1428
    }
 
1429
    else
 
1430
    {
 
1431
      read_set->reset(i);
 
1432
    }
 
1433
  }
3432
1434
}
3433
1435
 
3434
1436
uint32_t Table::find_shortest_key(const key_map *usable_keys)
3437
1439
  uint32_t best= MAX_KEY;
3438
1440
  if (usable_keys->any())
3439
1441
  {
3440
 
    for (uint32_t nr= 0; nr < s->keys ; nr++)
 
1442
    for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
3441
1443
    {
3442
1444
      if (usable_keys->test(nr))
3443
1445
      {
3464
1466
{
3465
1467
  for (; *ptr ; ptr++)
3466
1468
  {
3467
 
    if ((*ptr)->cmp_offset(s->rec_buff_length))
 
1469
    if ((*ptr)->cmp_offset(getShare()->rec_buff_length))
3468
1470
      return true;
3469
1471
  }
3470
1472
  return false;
3474
1476
 
3475
1477
bool Table::compare_record()
3476
1478
{
3477
 
  if (s->blob_fields + s->varchar_fields == 0)
3478
 
    return memcmp(this->record[0], this->record[1], (size_t) s->reclength);
 
1479
  if (not getShare()->blob_fields + getShare()->hasVariableWidth())
 
1480
    return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) getShare()->getRecordLength());
3479
1481
  
3480
1482
  /* Compare null bits */
3481
 
  if (memcmp(null_flags, null_flags + s->rec_buff_length, s->null_bytes))
 
1483
  if (memcmp(null_flags, null_flags + getShare()->rec_buff_length, getShare()->null_bytes))
3482
1484
    return true; /* Diff in NULL value */
3483
1485
 
3484
1486
  /* Compare updated fields */
3485
1487
  for (Field **ptr= field ; *ptr ; ptr++)
3486
1488
  {
3487
1489
    if (isWriteSet((*ptr)->field_index) &&
3488
 
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
 
1490
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
3489
1491
      return true;
3490
1492
  }
3491
1493
  return false;
3497
1499
 */
3498
1500
void Table::storeRecord()
3499
1501
{
3500
 
  memcpy(record[1], record[0], (size_t) s->reclength);
 
1502
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) getShare()->getRecordLength());
3501
1503
}
3502
1504
 
3503
1505
/*
3506
1508
 */
3507
1509
void Table::storeRecordAsInsert()
3508
1510
{
3509
 
  memcpy(insert_values, record[0], (size_t) s->reclength);
 
1511
  assert(insert_values.size() >= getShare()->getRecordLength());
 
1512
  memcpy(&insert_values[0], getInsertRecord(), (size_t) getShare()->getRecordLength());
3510
1513
}
3511
1514
 
3512
1515
/*
3515
1518
 */
3516
1519
void Table::storeRecordAsDefault()
3517
1520
{
3518
 
  memcpy(s->default_values, record[0], (size_t) s->reclength);
 
1521
  memcpy(getMutableShare()->getDefaultValues(), getInsertRecord(), (size_t) getShare()->getRecordLength());
3519
1522
}
3520
1523
 
3521
1524
/*
3524
1527
 */
3525
1528
void Table::restoreRecord()
3526
1529
{
3527
 
  memcpy(record[0], record[1], (size_t) s->reclength);
 
1530
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) getShare()->getRecordLength());
3528
1531
}
3529
1532
 
3530
1533
/*
3533
1536
 */
3534
1537
void Table::restoreRecordAsDefault()
3535
1538
{
3536
 
  memcpy(record[0], s->default_values, (size_t) s->reclength);
 
1539
  memcpy(getInsertRecord(), getMutableShare()->getDefaultValues(), (size_t) getShare()->getRecordLength());
3537
1540
}
3538
1541
 
3539
1542
/*
3543
1546
void Table::emptyRecord()
3544
1547
{
3545
1548
  restoreRecordAsDefault();
3546
 
  memset(null_flags, 255, s->null_bytes);
 
1549
  memset(null_flags, 255, getShare()->null_bytes);
3547
1550
}
3548
1551
 
3549
 
Table::Table()
3550
 
  : s(NULL),
3551
 
    field(NULL),
3552
 
    cursor(NULL),
3553
 
    next(NULL),
3554
 
    prev(NULL),
3555
 
    read_set(NULL),
3556
 
    write_set(NULL),
3557
 
    tablenr(0),
3558
 
    db_stat(0),
3559
 
    in_use(NULL),
3560
 
    insert_values(NULL),
3561
 
    key_info(NULL),
3562
 
    next_number_field(NULL),
3563
 
    found_next_number_field(NULL),
3564
 
    timestamp_field(NULL),
3565
 
    pos_in_table_list(NULL),
3566
 
    group(NULL),
3567
 
    alias(NULL),
3568
 
    null_flags(NULL),
3569
 
    lock_position(0),
3570
 
    lock_data_start(0),
3571
 
    lock_count(0),
3572
 
    used_fields(0),
3573
 
    status(0),
3574
 
    derived_select_number(0),
3575
 
    current_lock(F_UNLCK),
3576
 
    copy_blobs(false),
3577
 
    maybe_null(false),
3578
 
    null_row(false),
3579
 
    force_index(false),
3580
 
    distinct(false),
3581
 
    const_table(false),
3582
 
    no_rows(false),
3583
 
    key_read(false),
3584
 
    no_keyread(false),
3585
 
    open_placeholder(false),
3586
 
    locked_by_name(false),
3587
 
    no_cache(false),
3588
 
    auto_increment_field_not_null(false),
3589
 
    alias_name_used(false),
3590
 
    query_id(0),
3591
 
    quick_condition_rows(0),
3592
 
    timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
3593
 
    map(0)
 
1552
Table::Table() : 
 
1553
  field(NULL),
 
1554
  cursor(NULL),
 
1555
  next(NULL),
 
1556
  prev(NULL),
 
1557
  read_set(NULL),
 
1558
  write_set(NULL),
 
1559
  tablenr(0),
 
1560
  db_stat(0),
 
1561
  def_read_set(),
 
1562
  def_write_set(),
 
1563
  tmp_set(),
 
1564
  in_use(NULL),
 
1565
  key_info(NULL),
 
1566
  next_number_field(NULL),
 
1567
  found_next_number_field(NULL),
 
1568
  timestamp_field(NULL),
 
1569
  pos_in_table_list(NULL),
 
1570
  group(NULL),
 
1571
  null_flags(NULL),
 
1572
  lock_position(0),
 
1573
  lock_data_start(0),
 
1574
  lock_count(0),
 
1575
  used_fields(0),
 
1576
  status(0),
 
1577
  derived_select_number(0),
 
1578
  current_lock(F_UNLCK),
 
1579
  copy_blobs(false),
 
1580
  maybe_null(false),
 
1581
  null_row(false),
 
1582
  force_index(false),
 
1583
  distinct(false),
 
1584
  const_table(false),
 
1585
  no_rows(false),
 
1586
  key_read(false),
 
1587
  no_keyread(false),
 
1588
  open_placeholder(false),
 
1589
  locked_by_name(false),
 
1590
  no_cache(false),
 
1591
  auto_increment_field_not_null(false),
 
1592
  alias_name_used(false),
 
1593
  query_id(0),
 
1594
  quick_condition_rows(0),
 
1595
  timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
 
1596
  map(0)
3594
1597
{
3595
1598
  record[0]= (unsigned char *) 0;
3596
1599
  record[1]= (unsigned char *) 0;
3597
1600
 
 
1601
  reginfo.reset();
3598
1602
  covering_keys.reset();
3599
 
 
3600
1603
  quick_keys.reset();
3601
1604
  merge_keys.reset();
3602
1605
 
3609
1612
 
3610
1613
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
3611
1614
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
3612
 
 
3613
 
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
3614
 
  memset(&sort, 0, sizeof(filesort_info_st));
3615
1615
}
3616
1616
 
3617
1617
/*****************************************************************************
3634
1634
  */
3635
1635
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
3636
1636
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
3637
 
                    error, s->path.str);
 
1637
                  error, getShare()->getPath());
3638
1638
  print_error(error, MYF(0));
3639
1639
 
3640
1640
  return 1;
3648
1648
  null_row= 0;
3649
1649
  status= STATUS_NO_RECORD;
3650
1650
  maybe_null= table_list->outer_join;
3651
 
  TableList *embedding= table_list->embedding;
 
1651
  TableList *embedding= table_list->getEmbedding();
3652
1652
  while (!maybe_null && embedding)
3653
1653
  {
3654
1654
    maybe_null= embedding->outer_join;
3655
 
    embedding= embedding->embedding;
 
1655
    embedding= embedding->getEmbedding();
3656
1656
  }
3657
1657
  tablenr= table_number;
3658
1658
  map= (table_map) 1 << table_number;
3659
1659
  force_index= table_list->force_index;
3660
 
  covering_keys= s->keys_for_keyread;
 
1660
  covering_keys= getShare()->keys_for_keyread;
3661
1661
  merge_keys.reset();
3662
1662
}
3663
1663
 
3664
1664
 
3665
 
/*
3666
 
  Used by ALTER Table when the table is a temporary one. It changes something
3667
 
  only if the ALTER contained a RENAME clause (otherwise, table_name is the old
3668
 
  name).
3669
 
  Prepares a table cache key, which is the concatenation of db, table_name and
3670
 
  session->slave_proxy_id, separated by '\0'.
3671
 
*/
3672
 
 
3673
 
bool Table::renameAlterTemporaryTable(TableIdentifier &identifier)
 
1665
bool Table::fill_item_list(List<Item> *item_list) const
3674
1666
{
3675
 
  char *key;
3676
 
  uint32_t key_length;
3677
 
  TableShare *share= s;
3678
 
 
3679
 
  if (not (key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH)))
3680
 
    return true;
3681
 
 
3682
 
  key_length= TableShare::createKey(key, identifier);
3683
 
  share->set_table_cache_key(key, key_length);
3684
 
 
3685
 
  message::Table *message= share->getTableProto();
3686
 
 
3687
 
  message->set_name(identifier.getTableName());
3688
 
  message->set_schema(identifier.getSchemaName());
3689
 
 
 
1667
  /*
 
1668
    All Item_field's created using a direct pointer to a field
 
1669
    are fixed in Item_field constructor.
 
1670
  */
 
1671
  for (Field **ptr= field; *ptr; ptr++)
 
1672
  {
 
1673
    Item_field *item= new Item_field(*ptr);
 
1674
    if (!item || item_list->push_back(item))
 
1675
      return true;
 
1676
  }
3690
1677
  return false;
3691
1678
}
3692
1679
 
 
1680
 
 
1681
void Table::filesort_free_buffers(bool full)
 
1682
{
 
1683
  if (sort.record_pointers)
 
1684
  {
 
1685
    free((unsigned char*) sort.record_pointers);
 
1686
    sort.record_pointers=0;
 
1687
  }
 
1688
  if (full)
 
1689
  {
 
1690
    if (sort.sort_keys )
 
1691
    {
 
1692
      if ((unsigned char*) sort.sort_keys)
 
1693
        free((unsigned char*) sort.sort_keys);
 
1694
      sort.sort_keys= 0;
 
1695
    }
 
1696
    if (sort.buffpek)
 
1697
    {
 
1698
      if ((unsigned char*) sort.buffpek)
 
1699
        free((unsigned char*) sort.buffpek);
 
1700
      sort.buffpek= 0;
 
1701
      sort.buffpek_len= 0;
 
1702
    }
 
1703
  }
 
1704
 
 
1705
  if (sort.addon_buf)
 
1706
  {
 
1707
    free((char *) sort.addon_buf);
 
1708
    free((char *) sort.addon_field);
 
1709
    sort.addon_buf=0;
 
1710
    sort.addon_field=0;
 
1711
  }
 
1712
}
 
1713
 
3693
1714
} /* namespace drizzled */