~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

Replace MAX_(DATE|TIME).*_WIDTH defines in definitions.h with real (and correct) static const members to Temporal types.

This fixes the buffer overflow in https://bugs.launchpad.net/drizzle/+bug/373468

It also removes a handwritten snprintf in field/datetime.cc
However... this caused us to have to change Temporal to have a way to not
"convert" the int64_t value (so 20090101 becomes 20090101000000 etc) as it
has already been converted and we just want the Temporal type to do the
to_string conversion.

This still causes a failure in 'metadata' test due to size of timestamp type. I need feedback from Jay on when the usecond code comes into play to know the correct fix for this.

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