~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Monty Taylor
  • Date: 2009-08-17 18:46:08 UTC
  • mto: (1182.1.1 staging)
  • mto: This revision was merged to the branch mainline in revision 1183.
  • Revision ID: mordred@inaugust.com-20090817184608-0b2emowpjr9m6le7
"Fixed" the deadlock test. I'd still like someone to look at what's going on here.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
/* Some general useful functions */
18
18
 
19
 
#include "config.h"
20
 
 
21
 
#include <float.h>
22
 
#include <fcntl.h>
23
 
 
24
 
#include <string>
25
 
#include <vector>
26
 
#include <algorithm>
27
 
 
 
19
#include <drizzled/server_includes.h>
28
20
#include <drizzled/error.h>
29
21
#include <drizzled/gettext.h>
30
22
 
31
 
#include "drizzled/plugin/transactional_storage_engine.h"
32
 
#include "drizzled/plugin/authorization.h"
33
23
#include <drizzled/nested_join.h>
34
24
#include <drizzled/sql_parse.h>
35
25
#include <drizzled/item/sum.h>
42
32
#include <drizzled/field/double.h>
43
33
#include <drizzled/unireg.h>
44
34
#include <drizzled/message/table.pb.h>
45
 
#include "drizzled/sql_table.h"
46
 
#include "drizzled/charset.h"
47
 
#include "drizzled/internal/m_string.h"
48
 
#include "plugin/myisam/myisam.h"
49
35
 
50
36
#include <drizzled/item/string.h>
51
37
#include <drizzled/item/int.h>
52
38
#include <drizzled/item/decimal.h>
53
39
#include <drizzled/item/float.h>
54
40
#include <drizzled/item/null.h>
55
 
#include <drizzled/temporal.h>
56
 
 
57
 
#include "drizzled/table_proto.h"
 
41
 
 
42
#include <drizzled/table_proto.h>
 
43
 
 
44
#include <string>
 
45
#include <vector>
 
46
#include <algorithm>
 
47
 
58
48
 
59
49
using namespace std;
60
50
 
61
 
namespace drizzled
62
 
{
63
 
 
64
 
extern pid_t current_pid;
65
 
extern plugin::StorageEngine *heap_engine;
66
 
extern plugin::StorageEngine *myisam_engine;
67
 
 
68
 
/* Functions defined in this cursor */
 
51
/* Functions defined in this file */
69
52
 
70
53
void open_table_error(TableShare *share, int error, int db_errno,
71
54
                      myf errortype, int errarg);
80
63
  return (unsigned char*) (*buff)->field_name;
81
64
}
82
65
 
 
66
 
 
67
/*
 
68
  Returns pointer to '.frm' extension of the file name.
 
69
 
 
70
  SYNOPSIS
 
71
    fn_rext()
 
72
    name       file name
 
73
 
 
74
  DESCRIPTION
 
75
    Checks file name part starting with the rightmost '.' character,
 
76
    and returns it if it is equal to '.dfe'.
 
77
 
 
78
  TODO
 
79
    It is a good idea to get rid of this function modifying the code
 
80
    to garantee that the functions presently calling fn_rext() always
 
81
    get arguments in the same format: either with '.frm' or without '.frm'.
 
82
 
 
83
  RETURN VALUES
 
84
    Pointer to the '.frm' extension. If there is no extension,
 
85
    or extension is not '.frm', pointer at the end of file name.
 
86
*/
 
87
 
 
88
char *fn_rext(char *name)
 
89
{
 
90
  char *res= strrchr(name, '.');
 
91
  if (res && !strcmp(res, ".dfe"))
 
92
    return res;
 
93
  return name + strlen(name);
 
94
}
 
95
 
 
96
static TABLE_CATEGORY get_table_category(const LEX_STRING *db)
 
97
{
 
98
  assert(db != NULL);
 
99
 
 
100
  if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
 
101
      (my_strcasecmp(system_charset_info,
 
102
                    INFORMATION_SCHEMA_NAME.c_str(),
 
103
                    db->str) == 0))
 
104
  {
 
105
    return TABLE_CATEGORY_INFORMATION;
 
106
  }
 
107
 
 
108
  return TABLE_CATEGORY_USER;
 
109
}
 
110
 
 
111
 
83
112
/*
84
113
  Allocate a setup TableShare structure
85
114
 
97
126
TableShare *alloc_table_share(TableList *table_list, char *key,
98
127
                               uint32_t key_length)
99
128
{
100
 
  memory::Root mem_root;
 
129
  MEM_ROOT mem_root;
101
130
  TableShare *share;
102
131
  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);
 
132
  char path[FN_REFLEN];
 
133
  uint32_t path_length;
 
134
 
 
135
  path_length= build_table_filename(path, sizeof(path) - 1,
 
136
                                    table_list->db,
 
137
                                    table_list->table_name, false);
 
138
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
108
139
  if (multi_alloc_root(&mem_root,
109
140
                       &share, sizeof(*share),
110
141
                       &key_buff, key_length,
111
 
                       &path_buff, path.length() + 1,
 
142
                       &path_buff, path_length + 1,
112
143
                       NULL))
113
144
  {
114
145
    memset(share, 0, sizeof(*share));
115
146
 
116
147
    share->set_table_cache_key(key_buff, key, key_length);
117
148
 
118
 
    share->path.str= path_buff,
119
 
    share->path.length= path.length();
120
 
    strcpy(share->path.str, path.c_str());
 
149
    share->path.str= path_buff;
 
150
    share->path.length= path_length;
 
151
    strcpy(share->path.str, path);
121
152
    share->normalized_path.str=    share->path.str;
122
 
    share->normalized_path.length= path.length();
 
153
    share->normalized_path.length= path_length;
123
154
 
124
155
    share->version=       refresh_version;
125
156
 
137
168
 
138
169
  switch(proto_field_type)
139
170
  {
140
 
  case message::Table::Field::INTEGER:
 
171
  case drizzled::message::Table::Field::TINYINT:
 
172
    field_type= DRIZZLE_TYPE_TINY;
 
173
    break;
 
174
  case drizzled::message::Table::Field::INTEGER:
141
175
    field_type= DRIZZLE_TYPE_LONG;
142
176
    break;
143
 
  case message::Table::Field::DOUBLE:
 
177
  case drizzled::message::Table::Field::DOUBLE:
144
178
    field_type= DRIZZLE_TYPE_DOUBLE;
145
179
    break;
146
 
  case message::Table::Field::TIMESTAMP:
 
180
  case drizzled::message::Table::Field::TIMESTAMP:
147
181
    field_type= DRIZZLE_TYPE_TIMESTAMP;
148
182
    break;
149
 
  case message::Table::Field::BIGINT:
 
183
  case drizzled::message::Table::Field::BIGINT:
150
184
    field_type= DRIZZLE_TYPE_LONGLONG;
151
185
    break;
152
 
  case message::Table::Field::DATETIME:
 
186
  case drizzled::message::Table::Field::DATETIME:
153
187
    field_type= DRIZZLE_TYPE_DATETIME;
154
188
    break;
155
 
  case message::Table::Field::DATE:
 
189
  case drizzled::message::Table::Field::DATE:
156
190
    field_type= DRIZZLE_TYPE_DATE;
157
191
    break;
158
 
  case message::Table::Field::VARCHAR:
 
192
  case drizzled::message::Table::Field::VARCHAR:
159
193
    field_type= DRIZZLE_TYPE_VARCHAR;
160
194
    break;
161
 
  case message::Table::Field::DECIMAL:
162
 
    field_type= DRIZZLE_TYPE_DECIMAL;
 
195
  case drizzled::message::Table::Field::DECIMAL:
 
196
    field_type= DRIZZLE_TYPE_NEWDECIMAL;
163
197
    break;
164
 
  case message::Table::Field::ENUM:
 
198
  case drizzled::message::Table::Field::ENUM:
165
199
    field_type= DRIZZLE_TYPE_ENUM;
166
200
    break;
167
 
  case message::Table::Field::BLOB:
 
201
  case drizzled::message::Table::Field::BLOB:
168
202
    field_type= DRIZZLE_TYPE_BLOB;
169
203
    break;
170
204
  default:
171
 
    field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
 
205
    field_type= DRIZZLE_TYPE_TINY; /* Set value to kill GCC warning */
172
206
    assert(1);
173
207
  }
174
208
 
190
224
 
191
225
  switch(field_type)
192
226
  {
 
227
  case DRIZZLE_TYPE_TINY:
193
228
  case DRIZZLE_TYPE_LONG:
194
229
  case DRIZZLE_TYPE_LONGLONG:
195
230
    default_item= new Item_int(default_value->c_str(),
196
 
                               (int64_t) internal::my_strtoll10(default_value->c_str(),
197
 
                                                                NULL,
198
 
                                                                &error),
 
231
                               (int64_t) my_strtoll10(default_value->c_str(),
 
232
                                                      NULL,
 
233
                                                      &error),
199
234
                               default_value->length());
200
235
    break;
201
236
  case DRIZZLE_TYPE_DOUBLE:
229
264
                                    system_charset_info);
230
265
    }
231
266
    break;
232
 
  case DRIZZLE_TYPE_DECIMAL:
 
267
  case DRIZZLE_TYPE_NEWDECIMAL:
233
268
    default_item= new Item_decimal(default_value->c_str(),
234
269
                                   default_value->length(),
235
270
                                   system_charset_info);
239
274
  return default_item;
240
275
}
241
276
 
242
 
int parse_table_proto(Session& session,
243
 
                      message::Table &table,
 
277
int parse_table_proto(Session *session,
 
278
                      drizzled::message::Table &table,
244
279
                      TableShare *share)
245
280
{
246
281
  int error= 0;
 
282
  handler *handler_file= NULL;
247
283
 
248
 
  if (! table.IsInitialized())
249
284
  {
250
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table.InitializationErrorString().c_str());
251
 
    return ER_CORRUPT_TABLE_DEFINITION;
 
285
    share->storage_engine= ha_resolve_by_name(session, table.engine().name());
252
286
  }
253
287
 
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;
 
288
  drizzled::message::Table::TableOptions table_options;
260
289
 
261
290
  if (table.has_options())
262
291
    table_options= table.options();
263
292
 
264
 
  uint32_t db_create_options= 0;
 
293
  uint32_t db_create_options= HA_OPTION_LONG_BLOB_PTR;
265
294
 
266
295
  if (table_options.has_pack_keys())
267
296
  {
274
303
  if (table_options.pack_record())
275
304
    db_create_options|= HA_OPTION_PACK_RECORD;
276
305
 
 
306
  if (table_options.has_checksum())
 
307
  {
 
308
    if (table_options.checksum())
 
309
      db_create_options|= HA_OPTION_CHECKSUM;
 
310
    else
 
311
      db_create_options|= HA_OPTION_NO_CHECKSUM;
 
312
  }
 
313
 
 
314
  if (table_options.has_delay_key_write())
 
315
  {
 
316
    if (table_options.delay_key_write())
 
317
      db_create_options|= HA_OPTION_DELAY_KEY_WRITE;
 
318
    else
 
319
      db_create_options|= HA_OPTION_NO_DELAY_KEY_WRITE;
 
320
  }
 
321
 
277
322
  /* db_create_options was stored as 2 bytes in FRM
278
323
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
279
324
   */
280
325
  share->db_create_options= (db_create_options & 0x0000FFFF);
281
326
  share->db_options_in_use= share->db_create_options;
282
327
 
 
328
 
 
329
  share->avg_row_length= table_options.has_avg_row_length() ?
 
330
    table_options.avg_row_length() : 0;
 
331
 
 
332
  share->page_checksum= table_options.has_page_checksum() ?
 
333
    (table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
 
334
    : HA_CHOICE_UNDEF;
 
335
 
283
336
  share->row_type= table_options.has_row_type() ?
284
337
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
285
338
 
308
361
 
309
362
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
310
363
 
 
364
  share->db_low_byte_first= true;
 
365
 
 
366
  share->max_rows= table_options.has_max_rows() ?
 
367
    table_options.max_rows() : 0;
 
368
 
 
369
  share->min_rows= table_options.has_min_rows() ?
 
370
    table_options.min_rows() : 0;
 
371
 
311
372
  share->keys= table.indexes_size();
312
373
 
313
374
  share->key_parts= 0;
342
403
  KEY* keyinfo= share->key_info;
343
404
  for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
344
405
  {
345
 
    message::Table::Index indx= table.indexes(keynr);
 
406
    drizzled::message::Table::Index indx= table.indexes(keynr);
346
407
 
347
408
    keyinfo->table= 0;
348
409
    keyinfo->flags= 0;
352
413
 
353
414
    if (indx.has_options())
354
415
    {
355
 
      message::Table::Index::IndexOptions indx_options= indx.options();
 
416
      drizzled::message::Table::Index::IndexOptions indx_options= indx.options();
356
417
      if (indx_options.pack_key())
357
 
        keyinfo->flags|= HA_PACK_KEY;
 
418
        keyinfo->flags|= HA_PACK_KEY;
358
419
 
359
420
      if (indx_options.var_length_key())
360
 
        keyinfo->flags|= HA_VAR_LENGTH_PART;
 
421
        keyinfo->flags|= HA_VAR_LENGTH_PART;
361
422
 
362
423
      if (indx_options.null_part_key())
363
 
        keyinfo->flags|= HA_NULL_PART_KEY;
 
424
        keyinfo->flags|= HA_NULL_PART_KEY;
364
425
 
365
426
      if (indx_options.binary_pack_key())
366
 
        keyinfo->flags|= HA_BINARY_PACK_KEY;
 
427
        keyinfo->flags|= HA_BINARY_PACK_KEY;
367
428
 
368
429
      if (indx_options.has_partial_segments())
369
 
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
 
430
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
370
431
 
371
432
      if (indx_options.auto_generated_key())
372
 
        keyinfo->flags|= HA_GENERATED_KEY;
 
433
        keyinfo->flags|= HA_GENERATED_KEY;
373
434
 
374
435
      if (indx_options.has_key_block_size())
375
436
      {
376
 
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
377
 
        keyinfo->block_size= indx_options.key_block_size();
 
437
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
 
438
        keyinfo->block_size= indx_options.key_block_size();
378
439
      }
379
440
      else
380
441
      {
381
 
        keyinfo->block_size= 0;
 
442
        keyinfo->block_size= 0;
382
443
      }
 
444
 
383
445
    }
384
446
 
385
 
    switch (indx.type())
 
447
    switch(indx.type())
386
448
    {
387
 
    case message::Table::Index::UNKNOWN_INDEX:
 
449
    case drizzled::message::Table::Index::UNKNOWN_INDEX:
388
450
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
389
451
      break;
390
 
    case message::Table::Index::BTREE:
 
452
    case drizzled::message::Table::Index::BTREE:
391
453
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
392
454
      break;
393
 
    case message::Table::Index::HASH:
 
455
    case drizzled::message::Table::Index::RTREE:
 
456
      keyinfo->algorithm= HA_KEY_ALG_RTREE;
 
457
      break;
 
458
    case drizzled::message::Table::Index::HASH:
394
459
      keyinfo->algorithm= HA_KEY_ALG_HASH;
395
460
      break;
 
461
    case drizzled::message::Table::Index::FULLTEXT:
 
462
      keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
396
463
 
397
464
    default:
398
465
      /* TODO: suitable warning ? */
408
475
    keyinfo->rec_per_key= rec_per_key;
409
476
 
410
477
    for (unsigned int partnr= 0;
411
 
         partnr < keyinfo->key_parts;
412
 
         partnr++, key_part++)
 
478
        partnr < keyinfo->key_parts;
 
479
        partnr++, key_part++)
413
480
    {
414
 
      message::Table::Index::IndexPart part;
 
481
      drizzled::message::Table::Index::IndexPart part;
415
482
      part= indx.index_part(partnr);
416
483
 
417
484
      *rec_per_key++= 0;
424
491
      /* key_part->type ???? */
425
492
      key_part->key_part_flag= 0;
426
493
      if (part.has_in_reverse_order())
427
 
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
 
494
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
428
495
 
429
496
      key_part->length= part.compare_length();
430
497
 
432
499
 
433
500
      /* key_part->offset is set later */
434
501
      key_part->key_type= part.key_type();
 
502
 
435
503
    }
436
504
 
437
 
    if (! indx.has_comment())
 
505
    if (!indx.has_comment())
438
506
    {
439
507
      keyinfo->comment.length= 0;
440
508
      keyinfo->comment.str= NULL;
459
527
  share->keys_for_keyread.reset();
460
528
  set_prefix(share->keys_in_use, share->keys);
461
529
 
 
530
  if (table_options.has_connect_string())
 
531
  {
 
532
    size_t len= table_options.connect_string().length();
 
533
    const char* str= table_options.connect_string().c_str();
 
534
 
 
535
    share->connect_string.length= len;
 
536
    share->connect_string.str= strmake_root(&share->mem_root, str, len);
 
537
  }
 
538
 
 
539
  if (table_options.has_comment())
 
540
  {
 
541
    size_t len= table_options.comment().length();
 
542
    const char* str= table_options.comment().c_str();
 
543
 
 
544
    share->comment.length= len;
 
545
    share->comment.str= strmake_root(&share->mem_root, str, len);
 
546
  }
 
547
 
 
548
  share->key_block_size= table_options.has_key_block_size() ?
 
549
    table_options.key_block_size() : 0;
 
550
 
462
551
  share->fields= table.field_size();
463
552
 
464
553
  share->field= (Field**) alloc_root(&share->mem_root,
480
569
 
481
570
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
482
571
  {
483
 
    message::Table::Field pfield= table.field(fieldnr);
484
 
    if (pfield.constraints().is_nullable())
 
572
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
573
    if (pfield.has_constraints() && pfield.constraints().is_nullable())
485
574
      null_fields++;
486
575
 
487
576
    enum_field_types drizzle_field_type=
498
587
    case DRIZZLE_TYPE_BLOB:
499
588
    case DRIZZLE_TYPE_VARCHAR:
500
589
      {
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);
 
590
        drizzled::message::Table::Field::StringFieldOptions field_options=
 
591
          pfield.string_options();
 
592
 
 
593
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
 
594
                                            field_options.collation_id() : 0);
 
595
 
 
596
        if (!cs)
 
597
          cs= default_charset_info;
 
598
 
 
599
        field_pack_length[fieldnr]=
 
600
          calc_pack_length(drizzle_field_type,
 
601
                           field_options.length() * cs->mbmaxlen);
 
602
 
511
603
      }
512
604
      break;
513
605
    case DRIZZLE_TYPE_ENUM:
514
606
      {
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();
 
607
        drizzled::message::Table::Field::SetFieldOptions field_options=
 
608
          pfield.set_options();
 
609
 
 
610
        field_pack_length[fieldnr]=
 
611
          get_enum_pack_length(field_options.field_value_size());
 
612
 
 
613
        interval_count++;
 
614
        interval_parts+= field_options.field_value_size();
522
615
      }
523
616
      break;
524
 
    case DRIZZLE_TYPE_DECIMAL:
 
617
    case DRIZZLE_TYPE_NEWDECIMAL:
525
618
      {
526
 
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
 
619
        drizzled::message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
527
620
 
528
 
        field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
 
621
        field_pack_length[fieldnr]=
 
622
          my_decimal_get_binary_size(fo.precision(), fo.scale());
529
623
      }
530
624
      break;
531
625
    default:
535
629
 
536
630
    share->reclength+= field_pack_length[fieldnr];
537
631
    stored_columns_reclength+= field_pack_length[fieldnr];
 
632
 
538
633
  }
539
634
 
540
635
  /* data_offset added to stored_rec_length later */
543
638
  share->null_fields= null_fields;
544
639
 
545
640
  ulong null_bits= null_fields;
546
 
  if (! table_options.pack_record())
 
641
  if (!table_options.pack_record())
547
642
    null_bits++;
548
643
  ulong data_offset= (null_bits + 7)/8;
549
644
 
558
653
 
559
654
  unsigned char* record= NULL;
560
655
 
561
 
  if (! (record= (unsigned char *) alloc_root(&share->mem_root,
562
 
                                              rec_buff_length)))
 
656
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
 
657
                                     rec_buff_length)))
563
658
    abort();
564
659
 
565
660
  memset(record, 0, rec_buff_length);
566
661
 
567
662
  int null_count= 0;
568
663
 
569
 
  if (! table_options.pack_record())
 
664
  if (!table_options.pack_record())
570
665
  {
571
666
    null_count++; // one bit for delete mark.
572
667
    *record|= 1;
576
671
 
577
672
  if (interval_count)
578
673
  {
579
 
    share->intervals= (TYPELIB *) alloc_root(&share->mem_root,
580
 
                                           interval_count*sizeof(TYPELIB));
 
674
    share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
 
675
                                           interval_count*sizeof(TYPELIB));
581
676
  }
582
677
  else
583
678
    share->intervals= NULL;
584
679
 
585
 
  share->fieldnames.type_names= (const char **) alloc_root(&share->mem_root,
586
 
                                                          (share->fields + 1) * sizeof(char*));
 
680
  share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
 
681
                                  (share->fields+1)*sizeof(char*));
587
682
 
588
 
  share->fieldnames.type_lengths= (unsigned int *) alloc_root(&share->mem_root,
589
 
                                                             (share->fields + 1) * sizeof(unsigned int));
 
683
  share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
684
                                  (share->fields+1)*sizeof(unsigned int));
590
685
 
591
686
  share->fieldnames.type_names[share->fields]= NULL;
592
687
  share->fieldnames.type_lengths[share->fields]= 0;
601
696
 
602
697
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
603
698
  {
604
 
    message::Table::Field pfield= table.field(fieldnr);
 
699
    drizzled::message::Table::Field pfield= table.field(fieldnr);
605
700
 
606
701
    /* field names */
607
702
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
608
 
                                                        pfield.name().c_str(),
609
 
                                                        pfield.name().length());
 
703
                                                        pfield.name().c_str(),
 
704
                                                        pfield.name().length());
610
705
 
611
706
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
612
707
 
613
708
    /* enum typelibs */
614
 
    if (pfield.type() != message::Table::Field::ENUM)
 
709
    if (pfield.type() != drizzled::message::Table::Field::ENUM)
615
710
      continue;
616
711
 
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)
 
712
    drizzled::message::Table::Field::SetFieldOptions field_options=
 
713
      pfield.set_options();
 
714
 
 
715
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
 
716
                                             field_options.collation_id() : 0);
 
717
 
 
718
    if (!charset)
623
719
      charset= default_charset_info;
624
720
 
625
721
    TYPELIB *t= &(share->intervals[interval_nr]);
626
722
 
627
723
    t->type_names= (const char**)alloc_root(&share->mem_root,
628
 
                                            (field_options.field_value_size() + 1) * sizeof(char*));
 
724
                           (field_options.field_value_size()+1)*sizeof(char*));
629
725
 
630
726
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
631
 
                                                (field_options.field_value_size() + 1) * sizeof(unsigned int));
 
727
                     (field_options.field_value_size()+1)*sizeof(unsigned int));
632
728
 
633
729
    t->type_names[field_options.field_value_size()]= NULL;
634
730
    t->type_lengths[field_options.field_value_size()]= 0;
639
735
    for (int n= 0; n < field_options.field_value_size(); n++)
640
736
    {
641
737
      t->type_names[n]= strmake_root(&share->mem_root,
642
 
                                     field_options.field_value(n).c_str(),
643
 
                                     field_options.field_value(n).length());
 
738
                                     field_options.field_value(n).c_str(),
 
739
                                     field_options.field_value(n).length());
644
740
 
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.
 
741
      /* Go ask the charset what the length is as for "" length=1
 
742
         and there's stripping spaces or some other crack going on.
648
743
       */
649
744
      uint32_t lengthsp;
650
 
      lengthsp= charset->cset->lengthsp(charset,
651
 
                                        t->type_names[n],
652
 
                                        field_options.field_value(n).length());
 
745
      lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
 
746
                                        field_options.field_value(n).length());
653
747
      t->type_lengths[n]= lengthsp;
654
748
    }
655
749
    interval_nr++;
662
756
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
663
757
 
664
758
  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);
 
759
    use_hash= !hash_init(&share->name_hash,
 
760
                         system_charset_info,
 
761
                         share->fields, 0, 0,
 
762
                         (hash_get_key) get_field_name, 0, 0);
673
763
 
674
764
  unsigned char* null_pos= record;;
675
765
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
676
766
 
677
767
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
678
768
  {
679
 
    message::Table::Field pfield= table.field(fieldnr);
 
769
    drizzled::message::Table::Field pfield= table.field(fieldnr);
680
770
 
681
771
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
682
772
 
683
 
    switch (pfield.format())
 
773
    switch(pfield.format())
684
774
    {
685
 
    case message::Table::Field::DefaultFormat:
 
775
    case drizzled::message::Table::Field::DefaultFormat:
686
776
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
687
777
      break;
688
 
    case message::Table::Field::FixedFormat:
 
778
    case drizzled::message::Table::Field::FixedFormat:
689
779
      column_format= COLUMN_FORMAT_TYPE_FIXED;
690
780
      break;
691
 
    case message::Table::Field::DynamicFormat:
 
781
    case drizzled::message::Table::Field::DynamicFormat:
692
782
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
693
783
      break;
694
784
    default:
697
787
 
698
788
    Field::utype unireg_type= Field::NONE;
699
789
 
700
 
    if (pfield.has_numeric_options() &&
701
 
        pfield.numeric_options().is_autoincrement())
 
790
    if (pfield.has_numeric_options()
 
791
       && pfield.numeric_options().is_autoincrement())
702
792
    {
703
793
      unireg_type= Field::NEXT_NUMBER;
704
794
    }
705
795
 
706
 
    if (pfield.has_options() &&
707
 
        pfield.options().has_default_value() &&
708
 
        pfield.options().default_value().compare("NOW()") == 0)
 
796
    if (pfield.has_options()
 
797
       && pfield.options().has_default_value()
 
798
       && pfield.options().default_value().compare("NOW()") == 0)
709
799
    {
710
 
      if (pfield.options().has_update_value() &&
711
 
          pfield.options().update_value().compare("NOW()") == 0)
 
800
      if (pfield.options().has_update_value()
 
801
         && pfield.options().update_value().compare("NOW()") == 0)
712
802
      {
713
 
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
 
803
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
714
804
      }
715
 
      else if (! pfield.options().has_update_value())
 
805
      else if (!pfield.options().has_update_value())
716
806
      {
717
 
        unireg_type= Field::TIMESTAMP_DN_FIELD;
 
807
        unireg_type= Field::TIMESTAMP_DN_FIELD;
718
808
      }
719
809
      else
720
 
        assert(1); // Invalid update value.
 
810
        assert(1); // Invalid update value.
721
811
    }
722
 
    else if (pfield.has_options() &&
723
 
             pfield.options().has_update_value() &&
724
 
             pfield.options().update_value().compare("NOW()") == 0)
 
812
    else if (pfield.has_options()
 
813
             && pfield.options().has_update_value()
 
814
             && pfield.options().update_value().compare("NOW()") == 0)
725
815
    {
726
816
      unireg_type= Field::TIMESTAMP_UN_FIELD;
727
817
    }
747
837
 
748
838
    const CHARSET_INFO *charset= &my_charset_bin;
749
839
 
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
 
      }
 
840
    if (field_type==DRIZZLE_TYPE_BLOB
 
841
       || field_type==DRIZZLE_TYPE_VARCHAR)
 
842
    {
 
843
      drizzled::message::Table::Field::StringFieldOptions field_options=
 
844
        pfield.string_options();
 
845
 
 
846
      charset= get_charset(field_options.has_collation_id()?
 
847
                           field_options.collation_id() : 0);
 
848
 
 
849
      if (!charset)
 
850
        charset= default_charset_info;
 
851
 
 
852
    }
 
853
 
 
854
    if (field_type==DRIZZLE_TYPE_ENUM)
 
855
    {
 
856
      drizzled::message::Table::Field::SetFieldOptions field_options=
 
857
        pfield.set_options();
 
858
 
 
859
      charset= get_charset(field_options.has_collation_id()?
 
860
                           field_options.collation_id() : 0);
 
861
 
 
862
      if (!charset)
 
863
        charset= default_charset_info;
 
864
 
796
865
    }
797
866
 
798
867
    Item *default_value= NULL;
799
868
 
800
 
    if (pfield.options().has_default_value() ||
801
 
        pfield.options().has_default_null()  ||
802
 
        pfield.options().has_default_bin_value())
 
869
    if (pfield.options().has_default_value()
 
870
       || pfield.options().has_default_null()
 
871
       || pfield.options().has_default_bin_value())
803
872
    {
804
873
      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());
 
874
                                        charset,
 
875
                                        pfield.options().default_null(),
 
876
                                        &pfield.options().default_value(),
 
877
                                        &pfield.options().default_bin_value());
809
878
    }
810
879
 
 
880
    uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
811
881
 
812
882
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
813
883
    memset(&temp_table, 0, sizeof(temp_table));
814
884
    temp_table.s= share;
815
 
    temp_table.in_use= &session;
816
 
    temp_table.s->db_low_byte_first= true; //Cursor->low_byte_first();
 
885
    temp_table.in_use= session;
 
886
    temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
817
887
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
818
888
 
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]);
 
889
    Field* f= make_field(share, &share->mem_root,
 
890
                         record+field_offsets[fieldnr]+data_offset,
 
891
                         pfield.options().length(),
 
892
                         null_pos,
 
893
                         null_bit_pos,
 
894
                         pack_flag,
 
895
                         field_type,
 
896
                         charset,
 
897
                         (Field::utype) MTYP_TYPENR(unireg_type),
 
898
                         ((field_type==DRIZZLE_TYPE_ENUM)?
 
899
                         share->intervals+(interval_nr++)
 
900
                         : (TYPELIB*) 0),
 
901
                        share->fieldnames.type_names[fieldnr]);
919
902
 
920
903
    share->field[fieldnr]= f;
921
904
 
922
905
    f->init(&temp_table); /* blob default values need table obj */
923
906
 
924
 
    if (! (f->flags & NOT_NULL_FLAG))
 
907
    if (!(f->flags & NOT_NULL_FLAG))
925
908
    {
926
909
      *f->null_ptr|= f->null_bit;
927
 
      if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
928
 
        null_pos++;
 
910
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
 
911
        null_pos++;
929
912
      null_count++;
930
913
    }
931
914
 
932
915
    if (default_value)
933
916
    {
934
 
      enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
935
 
      session.count_cuted_fields= CHECK_FIELD_WARN;
 
917
      enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
 
918
      session->count_cuted_fields= CHECK_FIELD_WARN;
936
919
      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? */
 
920
      session->count_cuted_fields= old_count_cuted_fields;
 
921
      if (res != 0 && res != 3)
939
922
      {
940
923
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
941
924
        error= 1;
942
 
        goto err;
 
925
        goto err;
943
926
      }
944
927
    }
945
928
    else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
946
 
             (f->flags & NOT_NULL_FLAG))
 
929
            (f->flags & NOT_NULL_FLAG))
947
930
    {
948
931
      f->set_notnull();
949
932
      f->store((int64_t) 1, true);
957
940
 
958
941
    f->field_index= fieldnr;
959
942
    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
 
    {
 
943
    if (!default_value
 
944
       && !(f->unireg_check==Field::NEXT_NUMBER)
 
945
       && (f->flags & NOT_NULL_FLAG)
 
946
       && (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
965
947
      f->flags|= NO_DEFAULT_VALUE_FLAG;
966
 
    }
967
948
 
968
949
    if (f->unireg_check == Field::NEXT_NUMBER)
969
950
      share->found_next_number_field= &(share->field[fieldnr]);
986
967
         partnr < keyinfo->key_parts;
987
968
         partnr++, key_part++)
988
969
    {
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
 
       */
 
970
      /* Fix up key_part->offset by adding data_offset.
 
971
         We really should compute offset as well.
 
972
         But at least this way we are a little better. */
994
973
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
995
974
    }
996
975
  }
1003
982
  if (null_count & 7)
1004
983
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1005
984
 
1006
 
  share->null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
 
985
  share->null_bytes= (null_pos - (unsigned char*) record +
 
986
                      (null_bit_pos + 7) / 8);
1007
987
 
1008
988
  share->last_null_bit_pos= null_bit_pos;
1009
989
 
1010
990
  free(field_offsets);
1011
 
  field_offsets= NULL;
1012
991
  free(field_pack_length);
1013
 
  field_pack_length= NULL;
 
992
 
 
993
  if (!(handler_file= get_new_handler(share, session->mem_root,
 
994
                                     share->db_type())))
 
995
    abort(); // FIXME
1014
996
 
1015
997
  /* Fix key stuff */
1016
998
  if (share->key_parts)
1017
999
  {
1018
 
    uint32_t primary_key= (uint32_t) (find_type((char*) "PRIMARY",
1019
 
                                                &share->keynames, 3) - 1); /* @TODO Huh? */
 
1000
    uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
 
1001
                                       &share->keynames, 3) - 1);
 
1002
 
 
1003
    int64_t ha_option= handler_file->ha_table_flags();
1020
1004
 
1021
1005
    keyinfo= share->key_info;
1022
1006
    key_part= keyinfo->key_part;
1023
1007
 
1024
 
    for (uint32_t key= 0; key < share->keys; key++,keyinfo++)
 
1008
    for (uint32_t key= 0 ; key < share->keys ; key++,keyinfo++)
1025
1009
    {
1026
1010
      uint32_t usable_parts= 0;
1027
1011
 
1028
1012
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1029
1013
      {
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
 
        }
 
1014
        /*
 
1015
          If the UNIQUE key doesn't have NULL columns and is not a part key
 
1016
          declare this as a primary key.
 
1017
        */
 
1018
        primary_key=key;
 
1019
        for (uint32_t i= 0 ; i < keyinfo->key_parts ;i++)
 
1020
        {
 
1021
          uint32_t fieldnr= key_part[i].fieldnr;
 
1022
          if (!fieldnr ||
 
1023
              share->field[fieldnr-1]->null_ptr ||
 
1024
              share->field[fieldnr-1]->key_length() !=
 
1025
              key_part[i].length)
 
1026
          {
 
1027
            primary_key=MAX_KEY;                // Can't be used
 
1028
            break;
 
1029
          }
 
1030
        }
1046
1031
      }
1047
1032
 
1048
1033
      for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
1049
1034
      {
1050
1035
        Field *field;
1051
 
        if (! key_part->fieldnr)
 
1036
        if (!key_part->fieldnr)
1052
1037
        {
1053
 
          abort(); // goto err;
 
1038
//          error= 4;                             // Wrong file
 
1039
          abort(); // goto err;
1054
1040
        }
1055
1041
        field= key_part->field= share->field[key_part->fieldnr-1];
1056
1042
        key_part->type= field->key_type();
1084
1070
        if (field->key_length() == key_part->length &&
1085
1071
            !(field->flags & BLOB_FLAG))
1086
1072
        {
1087
 
          enum ha_key_alg algo= share->key_info[key].algorithm;
1088
 
          if (share->db_type()->index_flags(algo) & HA_KEYREAD_ONLY)
 
1073
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1089
1074
          {
1090
1075
            share->keys_for_keyread.set(key);
1091
1076
            field->part_of_key.set(key);
1092
1077
            field->part_of_key_not_clustered.set(key);
1093
1078
          }
1094
 
          if (share->db_type()->index_flags(algo) & HA_READ_ORDER)
 
1079
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1095
1080
            field->part_of_sortkey.set(key);
1096
1081
        }
1097
1082
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1105
1090
            If this field is part of the primary key and all keys contains
1106
1091
            the primary key, then we can use any key to find this column
1107
1092
          */
1108
 
          if (share->storage_engine->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX))
 
1093
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1109
1094
          {
1110
1095
            field->part_of_key= share->keys_in_use;
1111
1096
            if (field->part_of_sortkey.test(key))
1122
1107
      set_if_bigger(share->max_key_length,keyinfo->key_length+
1123
1108
                    keyinfo->key_parts);
1124
1109
      share->total_key_length+= keyinfo->key_length;
1125
 
 
1126
 
      if (keyinfo->flags & HA_NOSAME)
1127
 
      {
 
1110
      /*
 
1111
        MERGE tables do not have unique indexes. But every key could be
 
1112
        an unique index on the underlying MyISAM table. (Bug #10400)
 
1113
      */
 
1114
      if ((keyinfo->flags & HA_NOSAME) ||
 
1115
          (ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1128
1116
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
1129
 
      }
1130
1117
    }
1131
1118
    if (primary_key < MAX_KEY &&
1132
 
        (share->keys_in_use.test(primary_key)))
 
1119
        (share->keys_in_use.test(primary_key)))
1133
1120
    {
1134
1121
      share->primary_key= primary_key;
1135
1122
      /*
1136
 
        If we are using an integer as the primary key then allow the user to
1137
 
        refer to it as '_rowid'
 
1123
        If we are using an integer as the primary key then allow the user to
 
1124
        refer to it as '_rowid'
1138
1125
      */
1139
1126
      if (share->key_info[primary_key].key_parts == 1)
1140
1127
      {
1141
 
        Field *field= share->key_info[primary_key].key_part[0].field;
1142
 
        if (field && field->result_type() == INT_RESULT)
 
1128
        Field *field= share->key_info[primary_key].key_part[0].field;
 
1129
        if (field && field->result_type() == INT_RESULT)
1143
1130
        {
1144
1131
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
1145
 
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
 
1132
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1146
1133
                                      fieldnr);
1147
1134
        }
1148
1135
      }
 
1136
 
1149
1137
    }
1150
1138
    else
1151
1139
      share->primary_key = MAX_KEY; // we do not have a primary key
1183
1171
    for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
1184
1172
    {
1185
1173
      if ((*ptr)->flags & BLOB_FLAG)
1186
 
        (*save++)= k;
 
1174
        (*save++)= k;
1187
1175
    }
1188
1176
  }
1189
1177
 
1190
 
  share->db_low_byte_first= true; // @todo Question this.
 
1178
  share->db_low_byte_first= handler_file->low_byte_first();
1191
1179
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1192
1180
 
1193
1181
  my_bitmap_map *bitmaps;
1195
1183
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1196
1184
                                             share->column_bitmap_size)))
1197
1185
    goto err;
1198
 
  share->all_set.init(bitmaps, share->fields);
1199
 
  share->all_set.setAll();
 
1186
  bitmap_init(&share->all_set, bitmaps, share->fields);
 
1187
  bitmap_set_all(&share->all_set);
1200
1188
 
 
1189
  if (handler_file)
 
1190
    delete handler_file;
1201
1191
  return (0);
1202
1192
 
1203
1193
err:
1204
 
  if (field_offsets)
1205
 
    free(field_offsets);
1206
 
  if (field_pack_length)
1207
 
    free(field_pack_length);
1208
 
 
1209
1194
  share->error= error;
1210
 
  share->open_errno= errno;
 
1195
  share->open_errno= my_errno;
1211
1196
  share->errarg= 0;
1212
1197
  hash_free(&share->name_hash);
 
1198
  if (handler_file)
 
1199
    delete handler_file;
1213
1200
  share->open_table_error(error, share->open_errno, 0);
1214
1201
 
1215
1202
  return error;
1216
1203
}
1217
1204
 
1218
1205
/*
1219
 
  Read table definition from a binary / text based .frm cursor
 
1206
  Read table definition from a binary / text based .frm file
1220
1207
 
1221
1208
  SYNOPSIS
1222
1209
  open_table_def()
1223
 
  session               Thread Cursor
 
1210
  session               Thread handler
1224
1211
  share         Fill this with table definition
1225
1212
 
1226
1213
  NOTES
1233
1220
   0    ok
1234
1221
   1    Error (see open_table_error)
1235
1222
   2    Error (see open_table_error)
1236
 
   3    Wrong data in .frm cursor
 
1223
   3    Wrong data in .frm file
1237
1224
   4    Error (see open_table_error)
1238
1225
   5    Error (see open_table_error: charset unavailable)
1239
1226
   6    Unknown .frm version
1240
1227
*/
1241
1228
 
1242
 
int open_table_def(Session& session, TableIdentifier &identifier, TableShare *share)
 
1229
int open_table_def(Session *session, TableShare *share)
1243
1230
{
1244
1231
  int error;
1245
1232
  bool error_given;
1247
1234
  error= 1;
1248
1235
  error_given= 0;
1249
1236
 
1250
 
  message::Table table;
 
1237
  drizzled::message::Table table;
1251
1238
 
1252
 
  error= plugin::StorageEngine::getTableDefinition(session, identifier, table);
 
1239
  error= StorageEngine::getTableProto(share->normalized_path.str, &table);
1253
1240
 
1254
1241
  if (error != EEXIST)
1255
1242
  {
1256
 
    if (error > 0)
 
1243
    if (error>0)
1257
1244
    {
1258
 
      errno= error;
 
1245
      my_errno= error;
1259
1246
      error= 1;
1260
1247
    }
1261
1248
    else
1262
1249
    {
1263
 
      if (not table.IsInitialized())
 
1250
      if (!table.IsInitialized())
1264
1251
      {
1265
1252
        error= 4;
1266
1253
      }
1270
1257
 
1271
1258
  error= parse_table_proto(session, table, share);
1272
1259
 
1273
 
  share->table_category= TABLE_CATEGORY_USER;
 
1260
  share->table_category= get_table_category(& share->db);
 
1261
 
 
1262
  if (!error)
 
1263
    session->status_var.opened_shares++;
1274
1264
 
1275
1265
err_not_open:
1276
1266
  if (error && !error_given)
1277
1267
  {
1278
1268
    share->error= error;
1279
 
    share->open_table_error(error, (share->open_errno= errno), 0);
 
1269
    share->open_table_error(error, (share->open_errno= my_errno), 0);
1280
1270
  }
1281
1271
 
1282
1272
  return(error);
1288
1278
 
1289
1279
  SYNOPSIS
1290
1280
    open_table_from_share()
1291
 
    session                     Thread Cursor
 
1281
    session                     Thread handler
1292
1282
    share               Table definition
1293
1283
    alias               Alias for table
1294
1284
    db_stat             open flags (for example HA_OPEN_KEYFILE|
1295
1285
                        HA_OPEN_RNDFILE..) can be 0 (example in
1296
1286
                        ha_example_table)
 
1287
    prgflag             READ_ALL etc..
1297
1288
    ha_open_flags       HA_OPEN_ABORT_IF_LOCKED etc..
1298
1289
    outparam            result table
 
1290
    open_mode           One of OTM_OPEN|OTM_CREATE|OTM_ALTER
 
1291
                        if OTM_CREATE some errors are ignore
 
1292
                        if OTM_ALTER HA_OPEN is not called
1299
1293
 
1300
1294
  RETURN VALUES
1301
1295
   0    ok
1302
1296
   1    Error (see open_table_error)
1303
1297
   2    Error (see open_table_error)
1304
 
   3    Wrong data in .frm cursor
 
1298
   3    Wrong data in .frm file
1305
1299
   4    Error (see open_table_error)
1306
1300
   5    Error (see open_table_error: charset unavailable)
1307
1301
   7    Table definition has changed in engine
1308
1302
*/
1309
1303
 
1310
1304
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)
 
1305
                          uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
 
1306
                          Table *outparam, open_table_mode open_mode)
1313
1307
{
1314
1308
  int error;
1315
1309
  uint32_t records, i, bitmap_size;
1324
1318
  outparam->resetTable(session, share, db_stat);
1325
1319
 
1326
1320
 
1327
 
  if (not (outparam->alias= strdup(alias)))
 
1321
  if (!(outparam->alias= strdup(alias)))
1328
1322
    goto err;
1329
1323
 
1330
 
  /* Allocate Cursor */
1331
 
  if (not (outparam->cursor= share->db_type()->getCursor(*share, &outparam->mem_root)))
1332
 
    goto err;
 
1324
  /* Allocate handler */
 
1325
  if (!(prgflag & OPEN_FRM_FILE_ONLY))
 
1326
  {
 
1327
    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
 
1328
                                          share->db_type())))
 
1329
      goto err;
 
1330
  }
 
1331
  else
 
1332
  {
 
1333
    assert(!db_stat);
 
1334
  }
1333
1335
 
1334
1336
  error= 4;
1335
1337
  records= 0;
1336
 
  if ((db_stat & HA_OPEN_KEYFILE))
 
1338
  if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1337
1339
    records=1;
1338
 
 
1339
 
  records++;
 
1340
  if (prgflag & (READ_ALL+EXTRA_RECORD))
 
1341
    records++;
1340
1342
 
1341
1343
  if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1342
1344
                                   share->rec_buff_length * records)))
1343
 
    goto err;
 
1345
    goto err;                                   /* purecov: inspected */
1344
1346
 
1345
1347
  if (records == 0)
1346
1348
  {
1374
1376
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1375
1377
                                          (uint32_t) ((share->fields+1)*
1376
1378
                                                  sizeof(Field*)))))
1377
 
    goto err;
 
1379
    goto err;                                   /* purecov: inspected */
1378
1380
 
1379
1381
  outparam->field= field_ptr;
1380
1382
 
1448
1450
  bitmap_size= share->column_bitmap_size;
1449
1451
  if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1450
1452
    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);
 
1453
  bitmap_init(&outparam->def_read_set,
 
1454
              (my_bitmap_map*) bitmaps, share->fields);
 
1455
  bitmap_init(&outparam->def_write_set,
 
1456
              (my_bitmap_map*) (bitmaps+bitmap_size), share->fields);
 
1457
  bitmap_init(&outparam->tmp_set,
 
1458
              (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields);
1454
1459
  outparam->default_column_bitmaps();
1455
1460
 
1456
1461
  /* The table struct is now initialized;  Open the table */
1457
1462
  error= 2;
1458
 
  if (db_stat)
 
1463
  if (db_stat && open_mode != OTM_ALTER)
1459
1464
  {
1460
1465
    int ha_err;
1461
 
    if ((ha_err= (outparam->cursor->
 
1466
    if ((ha_err= (outparam->file->
1462
1467
                  ha_open(outparam, share->normalized_path.str,
1463
1468
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1464
1469
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1467
1472
                          HA_OPEN_ABORT_IF_LOCKED :
1468
1473
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1469
1474
    {
 
1475
      /* Set a flag if the table is crashed and it can be auto. repaired */
 
1476
      share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
 
1477
                       outparam->file->auto_repair() &&
 
1478
                       !(ha_open_flags & HA_OPEN_FOR_REPAIR));
 
1479
 
1470
1480
      switch (ha_err)
1471
1481
      {
1472
1482
        case HA_ERR_NO_SUCH_TABLE:
1473
1483
          /*
1474
1484
            The table did not exists in storage engine, use same error message
1475
 
            as if the .frm cursor didn't exist
 
1485
            as if the .frm file didn't exist
1476
1486
          */
1477
1487
          error= 1;
1478
 
          errno= ENOENT;
 
1488
          my_errno= ENOENT;
1479
1489
          break;
1480
1490
        case EMFILE:
1481
1491
          /*
1482
1492
            Too many files opened, use same error message as if the .frm
1483
 
            cursor can't open
 
1493
            file can't open
1484
1494
           */
1485
1495
          error= 1;
1486
 
          errno= EMFILE;
 
1496
          my_errno= EMFILE;
1487
1497
          break;
1488
1498
        default:
1489
 
          outparam->print_error(ha_err, MYF(0));
 
1499
          outparam->file->print_error(ha_err, MYF(0));
1490
1500
          error_reported= true;
1491
1501
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1492
1502
            error= 7;
1493
1503
          break;
1494
1504
      }
1495
 
      goto err;
 
1505
      goto err;                                 /* purecov: inspected */
1496
1506
    }
1497
1507
  }
1498
1508
 
1500
1510
  memset(bitmaps, 0, bitmap_size*3);
1501
1511
#endif
1502
1512
 
1503
 
  return 0;
 
1513
  session->status_var.opened_tables++;
 
1514
 
 
1515
  return (0);
1504
1516
 
1505
1517
 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
 
1518
  if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
 
1519
    share->open_table_error(error, my_errno, 0);
 
1520
  delete outparam->file;
 
1521
  outparam->file= 0;                            // For easier error checking
1510
1522
  outparam->db_stat= 0;
1511
1523
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on zeroed root
1512
1524
  free((char*) outparam->alias);
1513
1525
  return (error);
1514
1526
}
1515
1527
 
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
 
}
 
1528
/*
 
1529
  Free information allocated by openfrm
 
1530
 
 
1531
  SYNOPSIS
 
1532
    closefrm()
 
1533
    table               Table object to free
 
1534
    free_share          Is 1 if we also want to free table_share
 
1535
*/
1530
1536
 
1531
1537
int Table::closefrm(bool free_share)
1532
1538
{
1533
1539
  int error= 0;
1534
1540
 
1535
1541
  if (db_stat)
1536
 
    error= cursor->close();
 
1542
    error= file->close();
1537
1543
  free((char*) alias);
1538
1544
  alias= NULL;
1539
1545
  if (field)
1542
1548
      delete *ptr;
1543
1549
    field= 0;
1544
1550
  }
1545
 
  delete cursor;
1546
 
  cursor= 0;                            /* For easier errorchecking */
 
1551
  delete file;
 
1552
  file= 0;                              /* For easier errorchecking */
1547
1553
  if (free_share)
1548
1554
  {
1549
 
    if (s->tmp_table == message::Table::STANDARD)
 
1555
    if (s->tmp_table == NO_TMP_TABLE)
1550
1556
      TableShare::release(s);
1551
1557
    else
1552
1558
      s->free_table_share();
1557
1563
}
1558
1564
 
1559
1565
 
1560
 
void Table::resetTable(Session *session,
1561
 
                       TableShare *share,
1562
 
                       uint32_t db_stat_arg)
1563
 
{
1564
 
  s= share;
1565
 
  field= NULL;
1566
 
 
1567
 
  cursor= NULL;
1568
 
  next= NULL;
1569
 
  prev= NULL;
1570
 
 
1571
 
  read_set= NULL;
1572
 
  write_set= NULL;
1573
 
 
1574
 
  tablenr= 0;
1575
 
  db_stat= db_stat_arg;
1576
 
 
1577
 
  in_use= session;
1578
 
  record[0]= (unsigned char *) NULL;
1579
 
  record[1]= (unsigned char *) NULL;
1580
 
 
1581
 
  insert_values= NULL;
1582
 
  key_info= NULL;
1583
 
  next_number_field= NULL;
1584
 
  found_next_number_field= NULL;
1585
 
  timestamp_field= NULL;
1586
 
 
1587
 
  pos_in_table_list= NULL;
1588
 
  group= NULL;
1589
 
  alias= NULL;
1590
 
  null_flags= NULL;
1591
 
 
1592
 
  lock_position= 0;
1593
 
  lock_data_start= 0;
1594
 
  lock_count= 0;
1595
 
  used_fields= 0;
1596
 
  status= 0;
1597
 
  derived_select_number= 0;
1598
 
  current_lock= F_UNLCK;
1599
 
  copy_blobs= false;
1600
 
 
1601
 
  maybe_null= false;
1602
 
 
1603
 
  null_row= false;
1604
 
 
1605
 
  force_index= false;
1606
 
  distinct= false;
1607
 
  const_table= false;
1608
 
  no_rows= false;
1609
 
  key_read= false;
1610
 
  no_keyread= false;
1611
 
 
1612
 
  open_placeholder= false;
1613
 
  locked_by_name= false;
1614
 
  no_cache= false;
1615
 
 
1616
 
  auto_increment_field_not_null= false;
1617
 
  alias_name_used= false;
1618
 
 
1619
 
  query_id= 0;
1620
 
  quick_condition_rows= 0;
1621
 
 
1622
 
  timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1623
 
  map= 0;
1624
 
 
1625
 
  reginfo.reset();
1626
 
 
1627
 
  covering_keys.reset();
1628
 
 
1629
 
  quick_keys.reset();
1630
 
  merge_keys.reset();
1631
 
 
1632
 
  keys_in_use_for_query.reset();
1633
 
  keys_in_use_for_group_by.reset();
1634
 
  keys_in_use_for_order_by.reset();
1635
 
 
1636
 
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
1637
 
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
1638
 
 
1639
 
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
1640
 
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
1641
 
 
1642
 
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1643
 
  memset(&sort, 0, sizeof(filesort_info_st));
1644
 
}
1645
 
 
1646
 
 
1647
 
 
1648
1566
/* Deallocate temporary blob storage */
1649
1567
 
1650
1568
void free_blobs(register Table *table)
1657
1575
}
1658
1576
 
1659
1577
 
1660
 
        /* error message when opening a form cursor */
 
1578
        /* error message when opening a form file */
1661
1579
 
1662
1580
void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
1663
1581
{
1672
1590
      my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str);
1673
1591
    else
1674
1592
    {
1675
 
      snprintf(buff, sizeof(buff), "%s",normalized_path.str);
 
1593
      sprintf(buff,"%s",normalized_path.str);
1676
1594
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1677
1595
               errortype, buff, db_errno);
1678
1596
    }
1679
1597
    break;
1680
1598
  case 2:
1681
1599
  {
1682
 
    Cursor *cursor= 0;
 
1600
    handler *file= 0;
1683
1601
    const char *datext= "";
1684
1602
 
1685
1603
    if (db_type() != NULL)
1686
1604
    {
1687
 
      if ((cursor= db_type()->getCursor(*this, current_session->mem_root)))
 
1605
      if ((file= get_new_handler(this, current_session->mem_root,
 
1606
                                 db_type())))
1688
1607
      {
1689
1608
        if (!(datext= *db_type()->bas_ext()))
1690
1609
          datext= "";
1692
1611
    }
1693
1612
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1694
1613
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1695
 
    snprintf(buff, sizeof(buff), "%s%s", normalized_path.str,datext);
 
1614
    sprintf(buff,"%s%s", normalized_path.str,datext);
1696
1615
    my_error(err_no,errortype, buff, db_errno);
1697
 
    delete cursor;
 
1616
    delete file;
1698
1617
    break;
1699
1618
  }
1700
1619
  case 5:
1712
1631
    break;
1713
1632
  }
1714
1633
  case 6:
1715
 
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
 
1634
    sprintf(buff,"%s", normalized_path.str);
1716
1635
    my_printf_error(ER_NOT_FORM_FILE,
1717
1636
                    _("Table '%-.64s' was created with a different version "
1718
1637
                    "of Drizzle and cannot be read"),
1722
1641
    break;
1723
1642
  default:                              /* Better wrong error than none */
1724
1643
  case 4:
1725
 
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
 
1644
    sprintf(buff,"%s", normalized_path.str);
1726
1645
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1727
1646
    break;
1728
1647
  }
1730
1649
} /* open_table_error */
1731
1650
 
1732
1651
 
1733
 
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
 
1652
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
1734
1653
{
1735
1654
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
1736
1655
  if (!result)
1854
1773
{
1855
1774
  uint32_t field_count= s->fields;
1856
1775
 
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);
 
1776
  bitmap_init(&this->def_read_set, (my_bitmap_map*) bitmaps, field_count);
 
1777
  bitmap_init(&this->tmp_set, (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count);
1859
1778
 
1860
1779
  /* write_set and all_set are copies of read_set */
1861
1780
  def_write_set= def_read_set;
1862
1781
  s->all_set= def_read_set;
1863
 
  this->s->all_set.setAll();
 
1782
  bitmap_set_all(&this->s->all_set);
1864
1783
  default_column_bitmaps();
1865
1784
}
1866
1785
 
1867
1786
 
1868
1787
 
1869
 
void Table::updateCreateInfo(message::Table *table_proto)
 
1788
void Table::updateCreateInfo(HA_CREATE_INFO *create_info)
1870
1789
{
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());
 
1790
  create_info->max_rows= s->max_rows;
 
1791
  create_info->min_rows= s->min_rows;
 
1792
  create_info->table_options= s->db_create_options;
 
1793
  create_info->avg_row_length= s->avg_row_length;
 
1794
  create_info->block_size= s->block_size;
 
1795
  create_info->row_type= s->row_type;
 
1796
  create_info->default_table_charset= s->table_charset;
 
1797
  create_info->table_charset= 0;
 
1798
  create_info->comment= s->comment;
 
1799
 
 
1800
  return;
1874
1801
}
1875
1802
 
1876
1803
int rename_file_ext(const char * from,const char * to,const char * ext)
1881
1808
  from_s.append(ext);
1882
1809
  to_s.append(to);
1883
1810
  to_s.append(ext);
1884
 
  return (internal::my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
 
1811
  return (my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
1885
1812
}
1886
1813
 
1887
1814
/*
1918
1845
    org_name            Name of database and length
1919
1846
 
1920
1847
  RETURN
1921
 
    false error
1922
 
    true ok
 
1848
    0   ok
 
1849
    1   error
1923
1850
*/
1924
1851
 
1925
 
bool check_db_name(SchemaIdentifier &schema_identifier)
 
1852
bool check_db_name(LEX_STRING *org_name)
1926
1853
{
1927
 
  if (not plugin::Authorization::isAuthorized(current_session->getSecurityContext(), schema_identifier))
1928
 
  {
1929
 
    return false;
1930
 
  }
1931
 
 
1932
 
  return schema_identifier.isValid();
 
1854
  char *name= org_name->str;
 
1855
  uint32_t name_length= org_name->length;
 
1856
 
 
1857
  if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
 
1858
    return 1;
 
1859
 
 
1860
  if (name != any_db)
 
1861
    my_casedn_str(files_charset_info, name);
 
1862
 
 
1863
  return check_identifier_name(org_name);
1933
1864
}
1934
1865
 
 
1866
 
1935
1867
/*
1936
1868
  Allow anything as a table name, as long as it doesn't contain an
1937
1869
  ' ' at the end
2002
1934
    bitmap_clear_all(&table->def_read_set);
2003
1935
    bitmap_clear_all(&table->def_write_set);
2004
1936
  */
2005
 
  def_read_set.clearAll();
2006
 
  def_write_set.clearAll();
 
1937
  memset(def_read_set.bitmap, 0, s->column_bitmap_size*2);
2007
1938
  column_bitmaps_set(&def_read_set, &def_write_set);
2008
1939
}
2009
1940
 
2010
1941
 
2011
1942
/*
2012
 
  Tell Cursor we are going to call position() and rnd_pos() later.
 
1943
  Tell handler we are going to call position() and rnd_pos() later.
2013
1944
 
2014
1945
  NOTES:
2015
1946
  This is needed for handlers that uses the primary key to find the
2020
1951
void Table::prepare_for_position()
2021
1952
{
2022
1953
 
2023
 
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
 
1954
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
2024
1955
      s->primary_key < MAX_KEY)
2025
1956
  {
2026
1957
    mark_columns_used_by_index_no_reset(s->primary_key);
2041
1972
 
2042
1973
void Table::mark_columns_used_by_index(uint32_t index)
2043
1974
{
2044
 
  MyBitmap *bitmap= &tmp_set;
 
1975
  MY_BITMAP *bitmap= &tmp_set;
2045
1976
 
2046
 
  (void) cursor->extra(HA_EXTRA_KEYREAD);
2047
 
  bitmap->clearAll();
 
1977
  (void) file->extra(HA_EXTRA_KEYREAD);
 
1978
  bitmap_clear_all(bitmap);
2048
1979
  mark_columns_used_by_index_no_reset(index, bitmap);
2049
1980
  column_bitmaps_set(bitmap, bitmap);
2050
1981
  return;
2066
1997
{
2067
1998
 
2068
1999
  key_read= 0;
2069
 
  (void) cursor->extra(HA_EXTRA_NO_KEYREAD);
 
2000
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
2070
2001
  default_column_bitmaps();
2071
2002
  return;
2072
2003
}
2082
2013
}
2083
2014
 
2084
2015
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
2085
 
                                                MyBitmap *bitmap)
 
2016
                                                MY_BITMAP *bitmap)
2086
2017
{
2087
2018
  KEY_PART_INFO *key_part= key_info[index].key_part;
2088
2019
  KEY_PART_INFO *key_part_end= (key_part +
2089
2020
                                key_info[index].key_parts);
2090
2021
  for (;key_part != key_part_end; key_part++)
2091
 
    bitmap->setBit(key_part->fieldnr-1);
 
2022
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
2092
2023
}
2093
2024
 
2094
2025
 
2135
2066
void Table::mark_columns_needed_for_delete()
2136
2067
{
2137
2068
  /*
2138
 
    If the Cursor has no cursor capabilites, or we have row-based
 
2069
    If the handler has no cursor capabilites, or we have row-based
2139
2070
    replication active for the current statement, we have to read
2140
2071
    either the primary key, the hidden primary key or all columns to
2141
2072
    be able to do an delete
2151
2082
    mark_columns_used_by_index_no_reset(s->primary_key);
2152
2083
 
2153
2084
  /* If we the engine wants all predicates we mark all keys */
2154
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
2085
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2155
2086
  {
2156
2087
    Field **reg_field;
2157
2088
    for (reg_field= field ; *reg_field ; reg_field++)
2175
2106
    if neeed, either the primary key column or all columns to be read.
2176
2107
    (see mark_columns_needed_for_delete() for details)
2177
2108
 
2178
 
    If the engine has HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
 
2109
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
2179
2110
    mark all USED key columns as 'to-be-read'. This allows the engine to
2180
2111
    loop over the given record to find all changed keys and doesn't have to
2181
2112
    retrieve the row again.
2184
2115
void Table::mark_columns_needed_for_update()
2185
2116
{
2186
2117
  /*
2187
 
    If the Cursor has no cursor capabilites, or we have row-based
 
2118
    If the handler has no cursor capabilites, or we have row-based
2188
2119
    logging active for the current statement, we have to read either
2189
2120
    the primary key, the hidden primary key or all columns to be
2190
2121
    able to do an update
2198
2129
  else
2199
2130
    mark_columns_used_by_index_no_reset(s->primary_key);
2200
2131
 
2201
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
2132
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2202
2133
  {
2203
2134
    /* Mark all used key columns for read */
2204
2135
    Field **reg_field;
2214
2145
 
2215
2146
 
2216
2147
/*
2217
 
  Mark columns the Cursor needs for doing an insert
 
2148
  Mark columns the handler needs for doing an insert
2218
2149
 
2219
2150
  For now, this is used to mark fields used by the trigger
2220
2151
  as changed.
2255
2186
/**
2256
2187
  Create field for temporary table from given field.
2257
2188
 
2258
 
  @param session               Thread Cursor
 
2189
  @param session               Thread handler
2259
2190
  @param org_field    field from which new field will be created
2260
2191
  @param name         New field name
2261
2192
  @param table         Temporary table
2314
2245
 
2315
2246
 
2316
2247
/**
 
2248
  Create field for information schema table.
 
2249
 
 
2250
  @param session                Thread handler
 
2251
  @param table          Temporary table
 
2252
  @param item           Item to create a field for
 
2253
 
 
2254
  @retval
 
2255
    0                   on error
 
2256
  @retval
 
2257
    new_created field
 
2258
*/
 
2259
 
 
2260
static Field *create_tmp_field_for_schema(Item *item, Table *table)
 
2261
{
 
2262
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
 
2263
  {
 
2264
    Field *field;
 
2265
    if (item->max_length > MAX_FIELD_VARCHARLENGTH)
 
2266
      field= new Field_blob(item->max_length, item->maybe_null,
 
2267
                            item->name, item->collation.collation);
 
2268
    else
 
2269
      field= new Field_varstring(item->max_length, item->maybe_null,
 
2270
                                 item->name,
 
2271
                                 table->s, item->collation.collation);
 
2272
    if (field)
 
2273
      field->init(table);
 
2274
    return field;
 
2275
  }
 
2276
  return item->tmp_table_field_from_field_type(table, 0);
 
2277
}
 
2278
 
 
2279
 
 
2280
/**
2317
2281
  Create a temp table according to a field list.
2318
2282
 
2319
2283
  Given field pointers are changed to point at tmp_table for
2343
2307
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
2344
2308
#define RATIO_TO_PACK_ROWS             2
2345
2309
 
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
2310
Table *
2355
2311
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
2356
2312
                 order_st *group, bool distinct, bool save_sum_fields,
2357
2313
                 uint64_t select_options, ha_rows rows_limit,
2358
2314
                 const char *table_alias)
2359
2315
{
2360
 
  memory::Root *mem_root_save, own_root;
 
2316
  MEM_ROOT *mem_root_save, own_root;
2361
2317
  Table *table;
2362
2318
  TableShare *share;
2363
2319
  uint  i,field_count,null_count,null_pack_length;
2366
2322
  uint32_t  blob_count,group_null_items, string_count;
2367
2323
  uint32_t fieldnr= 0;
2368
2324
  ulong reclength, string_total_length;
2369
 
  bool  using_unique_constraint= false;
2370
 
  bool  use_packed_rows= true;
 
2325
  bool  using_unique_constraint= 0;
 
2326
  bool  use_packed_rows= 0;
2371
2327
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
2372
 
  char  *tmpname;
2373
 
  char  path[FN_REFLEN];
 
2328
  char  *tmpname,path[FN_REFLEN];
2374
2329
  unsigned char *pos, *group_buff, *bitmaps;
2375
2330
  unsigned char *null_flags;
2376
2331
  Field **reg_field, **from_field, **default_field;
2382
2337
  MI_COLUMNDEF *recinfo;
2383
2338
  uint32_t total_uneven_bit_length= 0;
2384
2339
  bool force_copy_fields= param->force_copy_fields;
2385
 
  uint64_t max_rows= 0;
2386
2340
 
2387
2341
  status_var_increment(session->status_var.created_tmp_tables);
2388
2342
 
2389
 
  make_internal_temporary_table_path(session, path);
 
2343
  /* if we run out of slots or we are not using tempool */
 
2344
  sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
 
2345
          session->thread_id, session->tmp_table++);
 
2346
 
 
2347
  /*
 
2348
    No need to change table name to lower case as we are only creating
 
2349
    MyISAM or HEAP tables here
 
2350
  */
 
2351
  fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
2352
 
2390
2353
 
2391
2354
  if (group)
2392
2355
  {
2393
 
    if (! param->quick_group)
 
2356
    if (!param->quick_group)
2394
2357
      group= 0;                                 // Can't use group key
2395
2358
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
2396
2359
    {
2402
2365
      */
2403
2366
      (*tmp->item)->marker= 4;
2404
2367
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
2405
 
        using_unique_constraint= true;
 
2368
        using_unique_constraint=1;
2406
2369
    }
2407
2370
    if (param->group_length >= MAX_BLOB_WIDTH)
2408
 
      using_unique_constraint= true;
 
2371
      using_unique_constraint=1;
2409
2372
    if (group)
2410
2373
      distinct= 0;                              // Can't use distinct
2411
2374
  }
2423
2386
  if (param->precomputed_group_by)
2424
2387
    copy_func_count+= param->sum_func_count;
2425
2388
 
2426
 
  memory::init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
2389
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
2427
2390
 
2428
2391
  if (!multi_alloc_root(&own_root,
2429
2392
                        &table, sizeof(*table),
2444
2407
                        &bitmaps, bitmap_buffer_size(field_count)*2,
2445
2408
                        NULL))
2446
2409
  {
2447
 
    return NULL;
 
2410
    return NULL;                                /* purecov: inspected */
2448
2411
  }
2449
2412
  /* CopyField belongs to Tmp_Table_Param, allocate it in Session mem_root */
2450
2413
  if (!(param->copy_field= copy= new (session->mem_root) CopyField[field_count]))
2451
2414
  {
2452
 
    free_root(&own_root, MYF(0));
2453
 
    return NULL;
 
2415
    free_root(&own_root, MYF(0));               /* purecov: inspected */
 
2416
    return NULL;                                /* purecov: inspected */
2454
2417
  }
2455
2418
  param->items_to_copy= copy_func;
2456
2419
  strcpy(tmpname,path);
2532
2495
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
2533
2496
                             tmp_from_field, &default_field[fieldnr],
2534
2497
                             group != 0,not_all_columns,
2535
 
                             false,
 
2498
                             distinct, 0,
2536
2499
                             param->convert_blob_length);
2537
2500
          if (!new_field)
2538
2501
            goto err;                                   // Should be OOM
2577
2540
        We here distinguish between UNION and multi-table-updates by the fact
2578
2541
        that in the later case group is set to the row pointer.
2579
2542
      */
2580
 
      Field *new_field=
 
2543
      Field *new_field= (param->schema_table) ?
 
2544
        create_tmp_field_for_schema(item, table) :
2581
2545
        create_tmp_field(session, table, item, type, &copy_func,
2582
2546
                         tmp_from_field, &default_field[fieldnr],
2583
2547
                         group != 0,
2584
2548
                         !force_copy_fields &&
2585
2549
                           (not_all_columns || group != 0),
 
2550
                         /*
 
2551
                           If item->marker == 4 then we force create_tmp_field
 
2552
                           to create a 64-bit longs for BIT fields because HEAP
 
2553
                           tables can't index BIT fields directly. We do the same
 
2554
                           for distinct, as we want the distinct index to be
 
2555
                           usable in this case too.
 
2556
                         */
 
2557
                         item->marker == 4 || param->bit_fields_as_long,
2586
2558
                         force_copy_fields,
2587
2559
                         param->convert_blob_length);
2588
2560
 
2636
2608
  /* If result table is small; use a heap */
2637
2609
  /* future: storage engine selection can be made dynamic? */
2638
2610
  if (blob_count || using_unique_constraint ||
2639
 
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
 
2611
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
2612
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
2640
2613
  {
2641
2614
    share->storage_engine= myisam_engine;
2642
 
    table->cursor= share->db_type()->getCursor(*share, &table->mem_root);
 
2615
    table->file= get_new_handler(share, &table->mem_root,
 
2616
                                 share->db_type());
2643
2617
    if (group &&
2644
 
        (param->group_parts > table->cursor->getEngine()->max_key_parts() ||
2645
 
         param->group_length > table->cursor->getEngine()->max_key_length()))
2646
 
      using_unique_constraint= true;
 
2618
        (param->group_parts > table->file->max_key_parts() ||
 
2619
         param->group_length > table->file->max_key_length()))
 
2620
      using_unique_constraint=1;
2647
2621
  }
2648
2622
  else
2649
2623
  {
2650
2624
    share->storage_engine= heap_engine;
2651
 
    table->cursor= share->db_type()->getCursor(*share, &table->mem_root);
 
2625
    table->file= get_new_handler(share, &table->mem_root,
 
2626
                                 share->db_type());
2652
2627
  }
2653
 
  if (! table->cursor)
 
2628
  if (!table->file)
2654
2629
    goto err;
2655
2630
 
2656
2631
 
2657
 
  if (! using_unique_constraint)
 
2632
  if (!using_unique_constraint)
2658
2633
    reclength+= group_null_items;       // null flag is stored separately
2659
2634
 
2660
2635
  share->blob_fields= blob_count;
2752
2727
         inherit the default value that is defined for the field referred
2753
2728
         by the Item_field object from which 'field' has been created.
2754
2729
      */
2755
 
      ptrdiff_t diff;
 
2730
      my_ptrdiff_t diff;
2756
2731
      Field *orig_field= default_field[i];
2757
2732
      /* Get the value from default_values */
2758
 
      diff= (ptrdiff_t) (orig_field->table->s->default_values-
 
2733
      diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
2759
2734
                            orig_field->table->record[0]);
2760
2735
      orig_field->move_field_offset(diff);      // Points now at default_values
2761
2736
      if (orig_field->is_real_null())
2794
2769
  table->storeRecordAsDefault();        // Make empty default record
2795
2770
 
2796
2771
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
2797
 
    max_rows= ~(uint64_t) 0;
 
2772
    share->max_rows= ~(ha_rows) 0;
2798
2773
  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);
 
2774
    share->max_rows= (ha_rows) (((share->db_type() == heap_engine) ?
 
2775
                                 min(session->variables.tmp_table_size,
 
2776
                                     session->variables.max_heap_table_size) :
 
2777
                                 session->variables.tmp_table_size) /
 
2778
                                 share->reclength);
2804
2779
 
2805
 
  set_if_bigger(max_rows, (uint64_t)1); // For dummy start options
 
2780
  set_if_bigger(share->max_rows,(ha_rows)1);    // For dummy start options
2806
2781
  /*
2807
2782
    Push the LIMIT clause to the temporary table creation, so that we
2808
2783
    materialize only up to 'rows_limit' records instead of all result records.
2809
2784
  */
2810
 
  set_if_smaller(max_rows, rows_limit);
2811
 
 
2812
 
  share->setMaxRows(max_rows);
2813
 
 
 
2785
  set_if_smaller(share->max_rows, rows_limit);
2814
2786
  param->end_write_records= rows_limit;
2815
2787
 
2816
2788
  keyinfo= param->keyinfo;
2839
2811
      key_part_info->offset= field->offset(table->record[0]);
2840
2812
      key_part_info->length= (uint16_t) field->key_length();
2841
2813
      key_part_info->type=   (uint8_t) field->key_type();
2842
 
      key_part_info->key_type= 
 
2814
      key_part_info->key_type =
2843
2815
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
2844
2816
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
2845
2817
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
2846
 
        0 : 1;
 
2818
        0 : FIELDFLAG_BINARY;
2847
2819
      if (!using_unique_constraint)
2848
2820
      {
2849
2821
        cur_group->buff=(char*) group_buff;
2852
2824
                                                     test(maybe_null),
2853
2825
                                                     field->null_ptr,
2854
2826
                                                     field->null_bit)))
2855
 
          goto err;
 
2827
          goto err; /* purecov: inspected */
2856
2828
        if (maybe_null)
2857
2829
        {
2858
2830
          /*
2926
2898
                                                0,
2927
2899
                                                (unsigned char*) 0,
2928
2900
                                                (uint32_t) 0,
 
2901
                                                Field::NONE,
2929
2902
                                                NULL,
2930
2903
                                                table->s,
2931
2904
                                                &my_charset_bin);
2932
2905
      if (!key_part_info->field)
2933
2906
        goto err;
2934
2907
      key_part_info->field->init(table);
2935
 
      key_part_info->key_type= 1; /* binary comparison */
 
2908
      key_part_info->key_type=FIELDFLAG_BINARY;
2936
2909
      key_part_info->type=    HA_KEYTYPE_BINARY;
2937
2910
      key_part_info++;
2938
2911
    }
2947
2920
      key_part_info->length=   (uint16_t) (*reg_field)->pack_length();
2948
2921
      /* TODO:
2949
2922
        The below method of computing the key format length of the
2950
 
        key part is a copy/paste from optimizer/range.cc, and table.cc.
 
2923
        key part is a copy/paste from opt_range.cc, and table.cc.
2951
2924
        This should be factored out, e.g. as a method of Field.
2952
2925
        In addition it is not clear if any of the Field::*_length
2953
2926
        methods is supposed to compute the same length. If so, it
2966
2939
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
2967
2940
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
2968
2941
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
2969
 
        0 : 1;
 
2942
        0 : FIELDFLAG_BINARY;
2970
2943
    }
2971
2944
  }
2972
2945
 
2973
2946
  if (session->is_fatal_error)                          // If end of memory
2974
 
    goto err;
 
2947
    goto err;                                    /* purecov: inspected */
2975
2948
  share->db_record_offset= 1;
2976
2949
  if (share->db_type() == myisam_engine)
2977
2950
  {
2988
2961
 
2989
2962
err:
2990
2963
  session->mem_root= mem_root_save;
2991
 
  table->free_tmp_table(session);
2992
 
  return NULL;
 
2964
  table->free_tmp_table(session);                    /* purecov: inspected */
 
2965
  return NULL;                          /* purecov: inspected */
2993
2966
}
2994
2967
 
2995
2968
/****************************************************************************/
2998
2971
  Create a reduced Table object with properly set up Field list from a
2999
2972
  list of field definitions.
3000
2973
 
3001
 
    The created table doesn't have a table Cursor associated with
 
2974
    The created table doesn't have a table handler associated with
3002
2975
    it, has no keys, no group/distinct, no copy_funcs array.
3003
2976
    The sole purpose of this Table object is to use the power of Field
3004
2977
    class to read/write data to/from table->record[0]. Then one can store
3049
3022
  List_iterator_fast<CreateField> it(field_list);
3050
3023
  while ((cdef= it++))
3051
3024
  {
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,
 
3025
    *field= make_field(share, NULL, 0, cdef->length,
 
3026
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
 
3027
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
 
3028
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
3062
3029
                       cdef->unireg_check,
3063
 
                       cdef->interval,
3064
 
                       cdef->field_name);
 
3030
                       cdef->interval, cdef->field_name);
3065
3031
    if (!*field)
3066
3032
      goto error;
3067
3033
    (*field)->init(table);
3129
3095
bool Table::open_tmp_table()
3130
3096
{
3131
3097
  int error;
3132
 
  if ((error=cursor->ha_open(this, s->table_name.str,O_RDWR,
 
3098
  if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
3133
3099
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
3134
3100
  {
3135
 
    print_error(error, MYF(0));
 
3101
    file->print_error(error,MYF(0)); /* purecov: inspected */
3136
3102
    db_stat= 0;
3137
3103
    return true;
3138
3104
  }
3139
 
  (void) cursor->extra(HA_EXTRA_QUICK);         /* Faster */
 
3105
  (void) file->extra(HA_EXTRA_QUICK);           /* Faster */
3140
3106
  return false;
3141
3107
}
3142
3108
 
3182
3148
 
3183
3149
  if (share->keys)
3184
3150
  {                                             // Get keys for ni_create
3185
 
    bool using_unique_constraint= false;
 
3151
    bool using_unique_constraint= 0;
3186
3152
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
3187
3153
                                            sizeof(*seg) * keyinfo->key_parts);
3188
3154
    if (!seg)
3189
3155
      goto err;
3190
3156
 
3191
3157
    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() ||
 
3158
    if (keyinfo->key_length >= file->max_key_length() ||
 
3159
        keyinfo->key_parts > file->max_key_parts() ||
3194
3160
        share->uniques)
3195
3161
    {
3196
3162
      /* Can't create a key; Make a unique constraint instead of a key */
3197
3163
      share->keys=    0;
3198
3164
      share->uniques= 1;
3199
 
      using_unique_constraint= true;
 
3165
      using_unique_constraint=1;
3200
3166
      memset(&uniquedef, 0, sizeof(uniquedef));
3201
3167
      uniquedef.keysegs=keyinfo->key_parts;
3202
3168
      uniquedef.seg=seg;
3226
3192
      seg->start=    keyinfo->key_part[i].offset;
3227
3193
      if (key_field->flags & BLOB_FLAG)
3228
3194
      {
3229
 
        seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
 
3195
        seg->type=
 
3196
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
3230
3197
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
3231
3198
        seg->bit_start= (uint8_t)(key_field->pack_length()
3232
3199
                                  - share->blob_ptr_size);
3246
3213
          In this case we have to tell MyISAM that two NULL should
3247
3214
          on INSERT be regarded at the same value
3248
3215
        */
3249
 
        if (! using_unique_constraint)
 
3216
        if (!using_unique_constraint)
3250
3217
          keydef.flag|= HA_NULL_ARE_EQUAL;
3251
3218
      }
3252
3219
    }
3265
3232
                       &create_info,
3266
3233
                       HA_CREATE_TMP_TABLE)))
3267
3234
  {
3268
 
    print_error(error, MYF(0));
 
3235
    file->print_error(error,MYF(0));    /* purecov: inspected */
3269
3236
    db_stat= 0;
3270
3237
    goto err;
3271
3238
  }
3279
3246
 
3280
3247
void Table::free_tmp_table(Session *session)
3281
3248
{
3282
 
  memory::Root own_root= mem_root;
 
3249
  MEM_ROOT own_root= mem_root;
3283
3250
  const char *save_proc_info;
3284
3251
 
3285
3252
  save_proc_info=session->get_proc_info();
3286
3253
  session->set_proc_info("removing tmp table");
3287
3254
 
3288
3255
  // Release latches since this can take a long time
3289
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
3256
  ha_release_temporary_latches(session);
3290
3257
 
3291
 
  if (cursor)
 
3258
  if (file)
3292
3259
  {
3293
3260
    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;
 
3261
      file->ha_drop_table(s->table_name.str);
 
3262
    else
 
3263
      s->db_type()->deleteTable(session, s->table_name.str);
 
3264
    delete file;
3300
3265
  }
3301
3266
 
3302
3267
  /* free blobs */
3326
3291
  if (table->s->db_type() != heap_engine ||
3327
3292
      error != HA_ERR_RECORD_FILE_FULL)
3328
3293
  {
3329
 
    table->print_error(error, MYF(0));
 
3294
    table->file->print_error(error,MYF(0));
3330
3295
    return true;
3331
3296
  }
3332
3297
 
3333
3298
  // Release latches since this can take a long time
3334
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
3299
  ha_release_temporary_latches(session);
3335
3300
 
3336
3301
  new_table= *table;
3337
3302
  share= *table->s;
3338
3303
  new_table.s= &share;
3339
3304
  new_table.s->storage_engine= myisam_engine;
3340
 
  if (not (new_table.cursor= new_table.s->db_type()->getCursor(share, &new_table.mem_root)))
 
3305
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
 
3306
                                        new_table.s->db_type())))
3341
3307
    return true;                                // End of memory
3342
3308
 
3343
3309
  save_proc_info=session->get_proc_info();
3349
3315
    goto err2;
3350
3316
  if (new_table.open_tmp_table())
3351
3317
    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);
 
3318
  if (table->file->indexes_are_disabled())
 
3319
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
 
3320
  table->file->ha_index_or_rnd_end();
 
3321
  table->file->ha_rnd_init(1);
3356
3322
  if (table->no_rows)
3357
3323
  {
3358
 
    new_table.cursor->extra(HA_EXTRA_NO_ROWS);
 
3324
    new_table.file->extra(HA_EXTRA_NO_ROWS);
3359
3325
    new_table.no_rows=1;
3360
3326
  }
3361
3327
 
3362
3328
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
3363
 
  new_table.cursor->extra(HA_EXTRA_WRITE_CACHE);
 
3329
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
3364
3330
 
3365
3331
  /*
3366
3332
    copy all old rows from heap table to MyISAM table
3367
3333
    This is the only code that uses record[1] to read/write but this
3368
3334
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
3369
3335
  */
3370
 
  while (!table->cursor->rnd_next(new_table.record[1]))
 
3336
  while (!table->file->rnd_next(new_table.record[1]))
3371
3337
  {
3372
 
    write_err= new_table.cursor->ha_write_row(new_table.record[1]);
 
3338
    write_err= new_table.file->ha_write_row(new_table.record[1]);
3373
3339
    if (write_err)
3374
3340
      goto err;
3375
3341
  }
3376
3342
  /* copy row that filled HEAP table */
3377
 
  if ((write_err=new_table.cursor->ha_write_row(table->record[0])))
 
3343
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
3378
3344
  {
3379
 
    if (new_table.cursor->is_fatal_error(write_err, HA_CHECK_DUP) ||
 
3345
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
3380
3346
        !ignore_last_dupp_key_error)
3381
3347
      goto err;
3382
3348
  }
3383
3349
 
3384
3350
  /* 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;
 
3351
  (void) table->file->ha_rnd_end();
 
3352
  (void) table->file->close();                  // This deletes the table !
 
3353
  delete table->file;
 
3354
  table->file= NULL;
3389
3355
  new_table.s= table->s;                       // Keep old share
3390
3356
  *table= new_table;
3391
3357
  *table->s= share;
3392
3358
 
3393
 
  table->cursor->change_table_ptr(table, table->s);
 
3359
  table->file->change_table_ptr(table, table->s);
3394
3360
  table->use_all_columns();
3395
3361
  if (save_proc_info)
3396
3362
  {
3402
3368
  return false;
3403
3369
 
3404
3370
 err:
3405
 
  table->print_error(write_err, MYF(0));
3406
 
  (void) table->cursor->ha_rnd_end();
3407
 
  (void) new_table.cursor->close();
3408
 
 
 
3371
  table->file->print_error(write_err, MYF(0));
 
3372
  (void) table->file->ha_rnd_end();
 
3373
  (void) new_table.file->close();
3409
3374
 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
 
 
 
3375
  new_table.s->db_type()->deleteTable(session, new_table.s->table_name.str);
3415
3376
 err2:
3416
 
  delete new_table.cursor;
 
3377
  delete new_table.file;
3417
3378
  session->set_proc_info(save_proc_info);
3418
3379
  table->mem_root= new_table.mem_root;
3419
3380
  return true;
3420
3381
}
3421
3382
 
3422
 
my_bitmap_map *Table::use_all_columns(MyBitmap *bitmap)
 
3383
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
3423
3384
{
3424
 
  my_bitmap_map *old= bitmap->getBitmap();
3425
 
  bitmap->setBitmap(s->all_set.getBitmap());
 
3385
  my_bitmap_map *old= bitmap->bitmap;
 
3386
  bitmap->bitmap= s->all_set.bitmap;
3426
3387
  return old;
3427
3388
}
3428
3389
 
3429
3390
void Table::restore_column_map(my_bitmap_map *old)
3430
3391
{
3431
 
  read_set->setBitmap(old);
 
3392
  read_set->bitmap= old;
3432
3393
}
3433
3394
 
3434
3395
uint32_t Table::find_shortest_key(const key_map *usable_keys)
3476
3437
{
3477
3438
  if (s->blob_fields + s->varchar_fields == 0)
3478
3439
    return memcmp(this->record[0], this->record[1], (size_t) s->reclength);
3479
 
  
3480
3440
  /* Compare null bits */
3481
 
  if (memcmp(null_flags, null_flags + s->rec_buff_length, s->null_bytes))
3482
 
    return true; /* Diff in NULL value */
3483
 
 
 
3441
  if (memcmp(null_flags,
 
3442
             null_flags + s->rec_buff_length,
 
3443
             s->null_bytes))
 
3444
    return true;                                // Diff in NULL value
3484
3445
  /* Compare updated fields */
3485
3446
  for (Field **ptr= field ; *ptr ; ptr++)
3486
3447
  {
3546
3507
  memset(null_flags, 255, s->null_bytes);
3547
3508
}
3548
3509
 
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)
3594
 
{
3595
 
  record[0]= (unsigned char *) 0;
3596
 
  record[1]= (unsigned char *) 0;
3597
 
 
3598
 
  covering_keys.reset();
3599
 
 
3600
 
  quick_keys.reset();
3601
 
  merge_keys.reset();
3602
 
 
3603
 
  keys_in_use_for_query.reset();
3604
 
  keys_in_use_for_group_by.reset();
3605
 
  keys_in_use_for_order_by.reset();
3606
 
 
3607
 
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
3608
 
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
3609
 
 
3610
 
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
3611
 
  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
 
}
3616
 
 
3617
3510
/*****************************************************************************
3618
3511
  The different ways to read a record
3619
3512
  Returns -1 if row was not found, 0 if row was found and 1 on errors
3620
3513
*****************************************************************************/
3621
3514
 
3622
 
/** Help function when we get some an error from the table Cursor. */
 
3515
/** Help function when we get some an error from the table handler. */
3623
3516
 
3624
3517
int Table::report_error(int error)
3625
3518
{
3635
3528
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
3636
3529
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
3637
3530
                    error, s->path.str);
3638
 
  print_error(error, MYF(0));
 
3531
  file->print_error(error,MYF(0));
3639
3532
 
3640
3533
  return 1;
3641
3534
}
3661
3554
  merge_keys.reset();
3662
3555
}
3663
3556
 
 
3557
Field *Table::find_field_in_table_sef(const char *name)
 
3558
{
 
3559
  Field **field_ptr;
 
3560
  if (s->name_hash.records)
 
3561
  {
 
3562
    field_ptr= (Field**)hash_search(&s->name_hash,(unsigned char*) name,
 
3563
                                    strlen(name));
 
3564
    if (field_ptr)
 
3565
    {
 
3566
      /*
 
3567
        field_ptr points to field in TableShare. Convert it to the matching
 
3568
        field in table
 
3569
      */
 
3570
      field_ptr= (field + (field_ptr - s->field));
 
3571
    }
 
3572
  }
 
3573
  else
 
3574
  {
 
3575
    if (!(field_ptr= field))
 
3576
      return (Field *)0;
 
3577
    for (; *field_ptr; ++field_ptr)
 
3578
      if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
 
3579
        break;
 
3580
  }
 
3581
  if (field_ptr)
 
3582
    return *field_ptr;
 
3583
  else
 
3584
    return (Field *)0;
 
3585
}
 
3586
 
3664
3587
 
3665
3588
/*
3666
3589
  Used by ALTER Table when the table is a temporary one. It changes something
3670
3593
  session->slave_proxy_id, separated by '\0'.
3671
3594
*/
3672
3595
 
3673
 
bool Table::renameAlterTemporaryTable(TableIdentifier &identifier)
 
3596
bool Table::rename_temporary_table(const char *db, const char *table_name)
3674
3597
{
3675
3598
  char *key;
3676
3599
  uint32_t key_length;
3677
3600
  TableShare *share= s;
3678
3601
 
3679
 
  if (not (key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH)))
3680
 
    return true;
 
3602
  if (!(key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH)))
 
3603
    return true;                                /* purecov: inspected */
3681
3604
 
3682
 
  key_length= TableShare::createKey(key, identifier);
 
3605
  key_length= TableShare::createKey(key, db, table_name);
3683
3606
  share->set_table_cache_key(key, key_length);
3684
3607
 
3685
 
  message::Table *message= share->getTableProto();
3686
 
 
3687
 
  message->set_name(identifier.getTableName());
3688
 
  message->set_schema(identifier.getSchemaName());
3689
 
 
3690
3608
  return false;
3691
3609
}
3692
3610
 
3693
 
} /* namespace drizzled */
 
3611
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
3612
template class List<String>;
 
3613
template class List_iterator<String>;
 
3614
#endif