~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-09-13 00:53:34 UTC
  • mto: (1126.9.2 captain-20090915-01)
  • mto: This revision was merged to the branch mainline in revision 1133.
  • Revision ID: osullivan.padraig@gmail.com-20090913005334-6wio2sbjugskfbm3
Added calls to the connection start/end dtrace probes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
/* Some general useful functions */
18
18
 
19
 
#include "config.h"
20
 
 
21
 
#include <float.h>
22
 
#include <fcntl.h>
23
 
 
24
 
#include <string>
25
 
#include <vector>
26
 
#include <algorithm>
27
 
 
 
19
#include <drizzled/server_includes.h>
28
20
#include <drizzled/error.h>
29
21
#include <drizzled/gettext.h>
30
22
 
31
 
#include "drizzled/plugin/transactional_storage_engine.h"
32
 
#include "drizzled/plugin/authorization.h"
33
23
#include <drizzled/nested_join.h>
34
24
#include <drizzled/sql_parse.h>
35
25
#include <drizzled/item/sum.h>
42
32
#include <drizzled/field/double.h>
43
33
#include <drizzled/unireg.h>
44
34
#include <drizzled/message/table.pb.h>
45
 
#include "drizzled/sql_table.h"
46
 
#include "drizzled/charset.h"
47
 
#include "drizzled/internal/m_string.h"
48
 
#include "plugin/myisam/myisam.h"
49
35
 
50
36
#include <drizzled/item/string.h>
51
37
#include <drizzled/item/int.h>
52
38
#include <drizzled/item/decimal.h>
53
39
#include <drizzled/item/float.h>
54
40
#include <drizzled/item/null.h>
55
 
#include <drizzled/temporal.h>
56
 
 
57
 
#include "drizzled/table_proto.h"
 
41
 
 
42
#include <drizzled/table_proto.h>
 
43
 
 
44
#include <string>
 
45
#include <vector>
 
46
#include <algorithm>
 
47
 
58
48
 
59
49
using namespace std;
60
 
 
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 */
 
50
using namespace drizzled;
 
51
 
 
52
/* Functions defined in this file */
69
53
 
70
54
void open_table_error(TableShare *share, int error, int db_errno,
71
55
                      myf errortype, int errarg);
80
64
  return (unsigned char*) (*buff)->field_name;
81
65
}
82
66
 
 
67
 
 
68
/*
 
69
  Returns pointer to '.frm' extension of the file name.
 
70
 
 
71
  SYNOPSIS
 
72
    fn_rext()
 
73
    name       file name
 
74
 
 
75
  DESCRIPTION
 
76
    Checks file name part starting with the rightmost '.' character,
 
77
    and returns it if it is equal to '.dfe'.
 
78
 
 
79
  TODO
 
80
    It is a good idea to get rid of this function modifying the code
 
81
    to garantee that the functions presently calling fn_rext() always
 
82
    get arguments in the same format: either with '.frm' or without '.frm'.
 
83
 
 
84
  RETURN VALUES
 
85
    Pointer to the '.frm' extension. If there is no extension,
 
86
    or extension is not '.frm', pointer at the end of file name.
 
87
*/
 
88
 
 
89
char *fn_rext(char *name)
 
90
{
 
91
  char *res= strrchr(name, '.');
 
92
  if (res && !strcmp(res, ".dfe"))
 
93
    return res;
 
94
  return name + strlen(name);
 
95
}
 
96
 
 
97
static TABLE_CATEGORY get_table_category(const LEX_STRING *db)
 
98
{
 
99
  assert(db != NULL);
 
100
 
 
101
  if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
 
102
      (my_strcasecmp(system_charset_info,
 
103
                    INFORMATION_SCHEMA_NAME.c_str(),
 
104
                    db->str) == 0))
 
105
  {
 
106
    return TABLE_CATEGORY_INFORMATION;
 
107
  }
 
108
 
 
109
  return TABLE_CATEGORY_USER;
 
110
}
 
111
 
 
112
 
83
113
/*
84
114
  Allocate a setup TableShare structure
85
115
 
97
127
TableShare *alloc_table_share(TableList *table_list, char *key,
98
128
                               uint32_t key_length)
99
129
{
100
 
  memory::Root mem_root;
 
130
  MEM_ROOT mem_root;
101
131
  TableShare *share;
102
132
  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);
 
133
  char path[FN_REFLEN];
 
134
  uint32_t path_length;
 
135
 
 
136
  path_length= build_table_filename(path, sizeof(path) - 1,
 
137
                                    table_list->db,
 
138
                                    table_list->table_name, false);
 
139
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
108
140
  if (multi_alloc_root(&mem_root,
109
141
                       &share, sizeof(*share),
110
142
                       &key_buff, key_length,
111
 
                       &path_buff, path.length() + 1,
 
143
                       &path_buff, path_length + 1,
112
144
                       NULL))
113
145
  {
114
146
    memset(share, 0, sizeof(*share));
115
147
 
116
148
    share->set_table_cache_key(key_buff, key, key_length);
117
149
 
118
 
    share->path.str= path_buff,
119
 
    share->path.length= path.length();
120
 
    strcpy(share->path.str, path.c_str());
 
150
    share->path.str= path_buff;
 
151
    share->path.length= path_length;
 
152
    strcpy(share->path.str, path);
121
153
    share->normalized_path.str=    share->path.str;
122
 
    share->normalized_path.length= path.length();
 
154
    share->normalized_path.length= path_length;
123
155
 
124
156
    share->version=       refresh_version;
125
157
 
137
169
 
138
170
  switch(proto_field_type)
139
171
  {
 
172
  case message::Table::Field::TINYINT:
 
173
    field_type= DRIZZLE_TYPE_TINY;
 
174
    break;
140
175
  case message::Table::Field::INTEGER:
141
176
    field_type= DRIZZLE_TYPE_LONG;
142
177
    break;
159
194
    field_type= DRIZZLE_TYPE_VARCHAR;
160
195
    break;
161
196
  case message::Table::Field::DECIMAL:
162
 
    field_type= DRIZZLE_TYPE_DECIMAL;
 
197
    field_type= DRIZZLE_TYPE_NEWDECIMAL;
163
198
    break;
164
199
  case message::Table::Field::ENUM:
165
200
    field_type= DRIZZLE_TYPE_ENUM;
168
203
    field_type= DRIZZLE_TYPE_BLOB;
169
204
    break;
170
205
  default:
171
 
    field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
 
206
    field_type= DRIZZLE_TYPE_TINY; /* Set value to kill GCC warning */
172
207
    assert(1);
173
208
  }
174
209
 
190
225
 
191
226
  switch(field_type)
192
227
  {
 
228
  case DRIZZLE_TYPE_TINY:
193
229
  case DRIZZLE_TYPE_LONG:
194
230
  case DRIZZLE_TYPE_LONGLONG:
195
231
    default_item= new Item_int(default_value->c_str(),
196
 
                               (int64_t) internal::my_strtoll10(default_value->c_str(),
197
 
                                                                NULL,
198
 
                                                                &error),
 
232
                               (int64_t) my_strtoll10(default_value->c_str(),
 
233
                                                      NULL,
 
234
                                                      &error),
199
235
                               default_value->length());
200
236
    break;
201
237
  case DRIZZLE_TYPE_DOUBLE:
229
265
                                    system_charset_info);
230
266
    }
231
267
    break;
232
 
  case DRIZZLE_TYPE_DECIMAL:
 
268
  case DRIZZLE_TYPE_NEWDECIMAL:
233
269
    default_item= new Item_decimal(default_value->c_str(),
234
270
                                   default_value->length(),
235
271
                                   system_charset_info);
239
275
  return default_item;
240
276
}
241
277
 
242
 
int parse_table_proto(Session& session,
 
278
int parse_table_proto(Session *session,
243
279
                      message::Table &table,
244
280
                      TableShare *share)
245
281
{
246
282
  int error= 0;
247
 
 
248
 
  if (! table.IsInitialized())
249
 
  {
250
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table.InitializationErrorString().c_str());
251
 
    return ER_CORRUPT_TABLE_DEFINITION;
252
 
  }
253
 
 
254
 
  share->setTableProto(new(nothrow) message::Table(table));
255
 
 
256
 
  share->storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
257
 
  assert(share->storage_engine); // We use an assert() here because we should never get this far and still have no suitable engine.
 
283
  handler *handler_file= NULL;
 
284
 
 
285
  share->setTableProto(new(std::nothrow) message::Table(table));
 
286
 
 
287
  share->storage_engine= ha_resolve_by_name(session, table.engine().name());
258
288
 
259
289
  message::Table::TableOptions table_options;
260
290
 
308
338
 
309
339
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
310
340
 
 
341
  share->db_low_byte_first= true;
 
342
 
311
343
  share->keys= table.indexes_size();
312
344
 
313
345
  share->key_parts= 0;
354
386
    {
355
387
      message::Table::Index::IndexOptions indx_options= indx.options();
356
388
      if (indx_options.pack_key())
357
 
        keyinfo->flags|= HA_PACK_KEY;
 
389
        keyinfo->flags|= HA_PACK_KEY;
358
390
 
359
391
      if (indx_options.var_length_key())
360
 
        keyinfo->flags|= HA_VAR_LENGTH_PART;
 
392
        keyinfo->flags|= HA_VAR_LENGTH_PART;
361
393
 
362
394
      if (indx_options.null_part_key())
363
 
        keyinfo->flags|= HA_NULL_PART_KEY;
 
395
        keyinfo->flags|= HA_NULL_PART_KEY;
364
396
 
365
397
      if (indx_options.binary_pack_key())
366
 
        keyinfo->flags|= HA_BINARY_PACK_KEY;
 
398
        keyinfo->flags|= HA_BINARY_PACK_KEY;
367
399
 
368
400
      if (indx_options.has_partial_segments())
369
 
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
 
401
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
370
402
 
371
403
      if (indx_options.auto_generated_key())
372
 
        keyinfo->flags|= HA_GENERATED_KEY;
 
404
        keyinfo->flags|= HA_GENERATED_KEY;
373
405
 
374
406
      if (indx_options.has_key_block_size())
375
407
      {
376
 
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
377
 
        keyinfo->block_size= indx_options.key_block_size();
 
408
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
 
409
        keyinfo->block_size= indx_options.key_block_size();
378
410
      }
379
411
      else
380
412
      {
381
 
        keyinfo->block_size= 0;
 
413
        keyinfo->block_size= 0;
382
414
      }
 
415
 
383
416
    }
384
417
 
385
 
    switch (indx.type())
 
418
    switch(indx.type())
386
419
    {
387
420
    case message::Table::Index::UNKNOWN_INDEX:
388
421
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
390
423
    case message::Table::Index::BTREE:
391
424
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
392
425
      break;
 
426
    case message::Table::Index::RTREE:
 
427
      keyinfo->algorithm= HA_KEY_ALG_RTREE;
 
428
      break;
393
429
    case message::Table::Index::HASH:
394
430
      keyinfo->algorithm= HA_KEY_ALG_HASH;
395
431
      break;
 
432
    case message::Table::Index::FULLTEXT:
 
433
      keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
396
434
 
397
435
    default:
398
436
      /* TODO: suitable warning ? */
408
446
    keyinfo->rec_per_key= rec_per_key;
409
447
 
410
448
    for (unsigned int partnr= 0;
411
 
         partnr < keyinfo->key_parts;
412
 
         partnr++, key_part++)
 
449
        partnr < keyinfo->key_parts;
 
450
        partnr++, key_part++)
413
451
    {
414
452
      message::Table::Index::IndexPart part;
415
453
      part= indx.index_part(partnr);
424
462
      /* key_part->type ???? */
425
463
      key_part->key_part_flag= 0;
426
464
      if (part.has_in_reverse_order())
427
 
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
 
465
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
428
466
 
429
467
      key_part->length= part.compare_length();
430
468
 
432
470
 
433
471
      /* key_part->offset is set later */
434
472
      key_part->key_type= part.key_type();
 
473
 
435
474
    }
436
475
 
437
 
    if (! indx.has_comment())
 
476
    if (!indx.has_comment())
438
477
    {
439
478
      keyinfo->comment.length= 0;
440
479
      keyinfo->comment.str= NULL;
459
498
  share->keys_for_keyread.reset();
460
499
  set_prefix(share->keys_in_use, share->keys);
461
500
 
 
501
  if (table_options.has_connect_string())
 
502
  {
 
503
    size_t len= table_options.connect_string().length();
 
504
    const char* str= table_options.connect_string().c_str();
 
505
 
 
506
    share->connect_string.length= len;
 
507
    share->connect_string.str= strmake_root(&share->mem_root, str, len);
 
508
  }
 
509
 
 
510
  share->key_block_size= table_options.has_key_block_size() ?
 
511
    table_options.key_block_size() : 0;
 
512
 
462
513
  share->fields= table.field_size();
463
514
 
464
515
  share->field= (Field**) alloc_root(&share->mem_root,
481
532
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
482
533
  {
483
534
    message::Table::Field pfield= table.field(fieldnr);
484
 
    if (pfield.constraints().is_nullable())
 
535
    if (pfield.has_constraints() && pfield.constraints().is_nullable())
485
536
      null_fields++;
486
537
 
487
538
    enum_field_types drizzle_field_type=
498
549
    case DRIZZLE_TYPE_BLOB:
499
550
    case DRIZZLE_TYPE_VARCHAR:
500
551
      {
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);
 
552
        message::Table::Field::StringFieldOptions field_options=
 
553
          pfield.string_options();
 
554
 
 
555
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
 
556
                                            field_options.collation_id() : 0);
 
557
 
 
558
        if (!cs)
 
559
          cs= default_charset_info;
 
560
 
 
561
        field_pack_length[fieldnr]=
 
562
          calc_pack_length(drizzle_field_type,
 
563
                           field_options.length() * cs->mbmaxlen);
 
564
 
511
565
      }
512
566
      break;
513
567
    case DRIZZLE_TYPE_ENUM:
514
568
      {
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();
 
569
        message::Table::Field::SetFieldOptions field_options=
 
570
          pfield.set_options();
 
571
 
 
572
        field_pack_length[fieldnr]=
 
573
          get_enum_pack_length(field_options.field_value_size());
 
574
 
 
575
        interval_count++;
 
576
        interval_parts+= field_options.field_value_size();
522
577
      }
523
578
      break;
524
 
    case DRIZZLE_TYPE_DECIMAL:
 
579
    case DRIZZLE_TYPE_NEWDECIMAL:
525
580
      {
526
 
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
527
 
 
528
 
        field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
 
581
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
 
582
        field_pack_length[fieldnr]=
 
583
          my_decimal_get_binary_size(fo.precision(), fo.scale());
529
584
      }
530
585
      break;
531
586
    default:
535
590
 
536
591
    share->reclength+= field_pack_length[fieldnr];
537
592
    stored_columns_reclength+= field_pack_length[fieldnr];
 
593
 
538
594
  }
539
595
 
540
596
  /* data_offset added to stored_rec_length later */
543
599
  share->null_fields= null_fields;
544
600
 
545
601
  ulong null_bits= null_fields;
546
 
  if (! table_options.pack_record())
 
602
  if (!table_options.pack_record())
547
603
    null_bits++;
548
604
  ulong data_offset= (null_bits + 7)/8;
549
605
 
558
614
 
559
615
  unsigned char* record= NULL;
560
616
 
561
 
  if (! (record= (unsigned char *) alloc_root(&share->mem_root,
562
 
                                              rec_buff_length)))
 
617
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
 
618
                                     rec_buff_length)))
563
619
    abort();
564
620
 
565
621
  memset(record, 0, rec_buff_length);
566
622
 
567
623
  int null_count= 0;
568
624
 
569
 
  if (! table_options.pack_record())
 
625
  if (!table_options.pack_record())
570
626
  {
571
627
    null_count++; // one bit for delete mark.
572
628
    *record|= 1;
576
632
 
577
633
  if (interval_count)
578
634
  {
579
 
    share->intervals= (TYPELIB *) alloc_root(&share->mem_root,
580
 
                                           interval_count*sizeof(TYPELIB));
 
635
    share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
 
636
                                           interval_count*sizeof(TYPELIB));
581
637
  }
582
638
  else
583
639
    share->intervals= NULL;
584
640
 
585
 
  share->fieldnames.type_names= (const char **) alloc_root(&share->mem_root,
586
 
                                                          (share->fields + 1) * sizeof(char*));
 
641
  share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
 
642
                                  (share->fields+1)*sizeof(char*));
587
643
 
588
 
  share->fieldnames.type_lengths= (unsigned int *) alloc_root(&share->mem_root,
589
 
                                                             (share->fields + 1) * sizeof(unsigned int));
 
644
  share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
645
                                  (share->fields+1)*sizeof(unsigned int));
590
646
 
591
647
  share->fieldnames.type_names[share->fields]= NULL;
592
648
  share->fieldnames.type_lengths[share->fields]= 0;
605
661
 
606
662
    /* field names */
607
663
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
608
 
                                                        pfield.name().c_str(),
609
 
                                                        pfield.name().length());
 
664
                                                        pfield.name().c_str(),
 
665
                                                        pfield.name().length());
610
666
 
611
667
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
612
668
 
614
670
    if (pfield.type() != message::Table::Field::ENUM)
615
671
      continue;
616
672
 
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)
 
673
    message::Table::Field::SetFieldOptions field_options= pfield.set_options();
 
674
 
 
675
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
 
676
                                             field_options.collation_id() : 0);
 
677
 
 
678
    if (!charset)
623
679
      charset= default_charset_info;
624
680
 
625
681
    TYPELIB *t= &(share->intervals[interval_nr]);
626
682
 
627
683
    t->type_names= (const char**)alloc_root(&share->mem_root,
628
 
                                            (field_options.field_value_size() + 1) * sizeof(char*));
 
684
                           (field_options.field_value_size()+1)*sizeof(char*));
629
685
 
630
686
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
631
 
                                                (field_options.field_value_size() + 1) * sizeof(unsigned int));
 
687
                     (field_options.field_value_size()+1)*sizeof(unsigned int));
632
688
 
633
689
    t->type_names[field_options.field_value_size()]= NULL;
634
690
    t->type_lengths[field_options.field_value_size()]= 0;
639
695
    for (int n= 0; n < field_options.field_value_size(); n++)
640
696
    {
641
697
      t->type_names[n]= strmake_root(&share->mem_root,
642
 
                                     field_options.field_value(n).c_str(),
643
 
                                     field_options.field_value(n).length());
 
698
                                     field_options.field_value(n).c_str(),
 
699
                                     field_options.field_value(n).length());
644
700
 
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.
 
701
      /* Go ask the charset what the length is as for "" length=1
 
702
         and there's stripping spaces or some other crack going on.
648
703
       */
649
704
      uint32_t lengthsp;
650
 
      lengthsp= charset->cset->lengthsp(charset,
651
 
                                        t->type_names[n],
652
 
                                        field_options.field_value(n).length());
 
705
      lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
 
706
                                        field_options.field_value(n).length());
653
707
      t->type_lengths[n]= lengthsp;
654
708
    }
655
709
    interval_nr++;
662
716
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
663
717
 
664
718
  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);
 
719
    use_hash= !hash_init(&share->name_hash,
 
720
                         system_charset_info,
 
721
                         share->fields, 0, 0,
 
722
                         (hash_get_key) get_field_name, 0, 0);
673
723
 
674
724
  unsigned char* null_pos= record;;
675
725
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
680
730
 
681
731
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
682
732
 
683
 
    switch (pfield.format())
 
733
    switch(pfield.format())
684
734
    {
685
735
    case message::Table::Field::DefaultFormat:
686
736
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
697
747
 
698
748
    Field::utype unireg_type= Field::NONE;
699
749
 
700
 
    if (pfield.has_numeric_options() &&
701
 
        pfield.numeric_options().is_autoincrement())
 
750
    if (pfield.has_numeric_options()
 
751
       && pfield.numeric_options().is_autoincrement())
702
752
    {
703
753
      unireg_type= Field::NEXT_NUMBER;
704
754
    }
705
755
 
706
 
    if (pfield.has_options() &&
707
 
        pfield.options().has_default_value() &&
708
 
        pfield.options().default_value().compare("NOW()") == 0)
 
756
    if (pfield.has_options()
 
757
       && pfield.options().has_default_value()
 
758
       && pfield.options().default_value().compare("NOW()") == 0)
709
759
    {
710
 
      if (pfield.options().has_update_value() &&
711
 
          pfield.options().update_value().compare("NOW()") == 0)
 
760
      if (pfield.options().has_update_value()
 
761
         && pfield.options().update_value().compare("NOW()") == 0)
712
762
      {
713
 
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
 
763
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
714
764
      }
715
 
      else if (! pfield.options().has_update_value())
 
765
      else if (!pfield.options().has_update_value())
716
766
      {
717
 
        unireg_type= Field::TIMESTAMP_DN_FIELD;
 
767
        unireg_type= Field::TIMESTAMP_DN_FIELD;
718
768
      }
719
769
      else
720
 
        assert(1); // Invalid update value.
 
770
        assert(1); // Invalid update value.
721
771
    }
722
 
    else if (pfield.has_options() &&
723
 
             pfield.options().has_update_value() &&
724
 
             pfield.options().update_value().compare("NOW()") == 0)
 
772
    else if (pfield.has_options()
 
773
             && pfield.options().has_update_value()
 
774
             && pfield.options().update_value().compare("NOW()") == 0)
725
775
    {
726
776
      unireg_type= Field::TIMESTAMP_UN_FIELD;
727
777
    }
747
797
 
748
798
    const CHARSET_INFO *charset= &my_charset_bin;
749
799
 
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
 
      }
 
800
    if (field_type==DRIZZLE_TYPE_BLOB
 
801
       || field_type==DRIZZLE_TYPE_VARCHAR)
 
802
    {
 
803
      message::Table::Field::StringFieldOptions field_options=
 
804
        pfield.string_options();
 
805
 
 
806
      charset= get_charset(field_options.has_collation_id()?
 
807
                           field_options.collation_id() : 0);
 
808
 
 
809
      if (!charset)
 
810
        charset= default_charset_info;
 
811
 
 
812
    }
 
813
 
 
814
    if (field_type==DRIZZLE_TYPE_ENUM)
 
815
    {
 
816
      message::Table::Field::SetFieldOptions field_options=
 
817
        pfield.set_options();
 
818
 
 
819
      charset= get_charset(field_options.has_collation_id()?
 
820
                           field_options.collation_id() : 0);
 
821
 
 
822
      if (!charset)
 
823
        charset= default_charset_info;
 
824
 
796
825
    }
797
826
 
798
827
    Item *default_value= NULL;
799
828
 
800
 
    if (pfield.options().has_default_value() ||
801
 
        pfield.options().has_default_null()  ||
802
 
        pfield.options().has_default_bin_value())
 
829
    if (pfield.options().has_default_value()
 
830
       || pfield.options().has_default_null()
 
831
       || pfield.options().has_default_bin_value())
803
832
    {
804
833
      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());
 
834
                                        charset,
 
835
                                        pfield.options().default_null(),
 
836
                                        &pfield.options().default_value(),
 
837
                                        &pfield.options().default_bin_value());
809
838
    }
810
839
 
 
840
    uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
811
841
 
812
842
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
813
843
    memset(&temp_table, 0, sizeof(temp_table));
814
844
    temp_table.s= share;
815
 
    temp_table.in_use= &session;
816
 
    temp_table.s->db_low_byte_first= true; //Cursor->low_byte_first();
 
845
    temp_table.in_use= session;
 
846
    temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
817
847
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
818
848
 
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]);
 
849
    Field* f= make_field(share, &share->mem_root,
 
850
                         record+field_offsets[fieldnr]+data_offset,
 
851
                         pfield.options().length(),
 
852
                         null_pos,
 
853
                         null_bit_pos,
 
854
                         pack_flag,
 
855
                         field_type,
 
856
                         charset,
 
857
                         (Field::utype) MTYP_TYPENR(unireg_type),
 
858
                         ((field_type==DRIZZLE_TYPE_ENUM)?
 
859
                         share->intervals+(interval_nr++)
 
860
                         : (TYPELIB*) 0),
 
861
                        share->fieldnames.type_names[fieldnr]);
919
862
 
920
863
    share->field[fieldnr]= f;
921
864
 
922
865
    f->init(&temp_table); /* blob default values need table obj */
923
866
 
924
 
    if (! (f->flags & NOT_NULL_FLAG))
 
867
    if (!(f->flags & NOT_NULL_FLAG))
925
868
    {
926
869
      *f->null_ptr|= f->null_bit;
927
 
      if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
928
 
        null_pos++;
 
870
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
 
871
        null_pos++;
929
872
      null_count++;
930
873
    }
931
874
 
932
875
    if (default_value)
933
876
    {
934
 
      enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
935
 
      session.count_cuted_fields= CHECK_FIELD_WARN;
 
877
      enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
 
878
      session->count_cuted_fields= CHECK_FIELD_WARN;
936
879
      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? */
 
880
      session->count_cuted_fields= old_count_cuted_fields;
 
881
      if (res != 0 && res != 3)
939
882
      {
940
883
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
941
884
        error= 1;
942
 
        goto err;
 
885
        goto err;
943
886
      }
944
887
    }
945
888
    else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
946
 
             (f->flags & NOT_NULL_FLAG))
 
889
            (f->flags & NOT_NULL_FLAG))
947
890
    {
948
891
      f->set_notnull();
949
892
      f->store((int64_t) 1, true);
957
900
 
958
901
    f->field_index= fieldnr;
959
902
    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
 
    {
 
903
    if (!default_value
 
904
       && !(f->unireg_check==Field::NEXT_NUMBER)
 
905
       && (f->flags & NOT_NULL_FLAG)
 
906
       && (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
965
907
      f->flags|= NO_DEFAULT_VALUE_FLAG;
966
 
    }
967
908
 
968
909
    if (f->unireg_check == Field::NEXT_NUMBER)
969
910
      share->found_next_number_field= &(share->field[fieldnr]);
986
927
         partnr < keyinfo->key_parts;
987
928
         partnr++, key_part++)
988
929
    {
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
 
       */
 
930
      /* Fix up key_part->offset by adding data_offset.
 
931
         We really should compute offset as well.
 
932
         But at least this way we are a little better. */
994
933
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
995
934
    }
996
935
  }
1003
942
  if (null_count & 7)
1004
943
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1005
944
 
1006
 
  share->null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
 
945
  share->null_bytes= (null_pos - (unsigned char*) record +
 
946
                      (null_bit_pos + 7) / 8);
1007
947
 
1008
948
  share->last_null_bit_pos= null_bit_pos;
1009
949
 
1010
950
  free(field_offsets);
1011
 
  field_offsets= NULL;
1012
951
  free(field_pack_length);
1013
 
  field_pack_length= NULL;
 
952
 
 
953
  if (!(handler_file= get_new_handler(share, session->mem_root,
 
954
                                     share->db_type())))
 
955
    abort(); // FIXME
1014
956
 
1015
957
  /* Fix key stuff */
1016
958
  if (share->key_parts)
1017
959
  {
1018
 
    uint32_t primary_key= (uint32_t) (find_type((char*) "PRIMARY",
1019
 
                                                &share->keynames, 3) - 1); /* @TODO Huh? */
 
960
    uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
 
961
                                       &share->keynames, 3) - 1);
 
962
 
 
963
    int64_t ha_option= handler_file->ha_table_flags();
1020
964
 
1021
965
    keyinfo= share->key_info;
1022
966
    key_part= keyinfo->key_part;
1023
967
 
1024
 
    for (uint32_t key= 0; key < share->keys; key++,keyinfo++)
 
968
    for (uint32_t key= 0 ; key < share->keys ; key++,keyinfo++)
1025
969
    {
1026
970
      uint32_t usable_parts= 0;
1027
971
 
1028
972
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1029
973
      {
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
 
        }
 
974
        /*
 
975
          If the UNIQUE key doesn't have NULL columns and is not a part key
 
976
          declare this as a primary key.
 
977
        */
 
978
        primary_key=key;
 
979
        for (uint32_t i= 0 ; i < keyinfo->key_parts ;i++)
 
980
        {
 
981
          uint32_t fieldnr= key_part[i].fieldnr;
 
982
          if (!fieldnr ||
 
983
              share->field[fieldnr-1]->null_ptr ||
 
984
              share->field[fieldnr-1]->key_length() !=
 
985
              key_part[i].length)
 
986
          {
 
987
            primary_key=MAX_KEY;                // Can't be used
 
988
            break;
 
989
          }
 
990
        }
1046
991
      }
1047
992
 
1048
993
      for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
1049
994
      {
1050
995
        Field *field;
1051
 
        if (! key_part->fieldnr)
 
996
        if (!key_part->fieldnr)
1052
997
        {
1053
 
          abort(); // goto err;
 
998
//          error= 4;                             // Wrong file
 
999
          abort(); // goto err;
1054
1000
        }
1055
1001
        field= key_part->field= share->field[key_part->fieldnr-1];
1056
1002
        key_part->type= field->key_type();
1084
1030
        if (field->key_length() == key_part->length &&
1085
1031
            !(field->flags & BLOB_FLAG))
1086
1032
        {
1087
 
          enum ha_key_alg algo= share->key_info[key].algorithm;
1088
 
          if (share->db_type()->index_flags(algo) & HA_KEYREAD_ONLY)
 
1033
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1089
1034
          {
1090
1035
            share->keys_for_keyread.set(key);
1091
1036
            field->part_of_key.set(key);
1092
1037
            field->part_of_key_not_clustered.set(key);
1093
1038
          }
1094
 
          if (share->db_type()->index_flags(algo) & HA_READ_ORDER)
 
1039
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1095
1040
            field->part_of_sortkey.set(key);
1096
1041
        }
1097
1042
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1105
1050
            If this field is part of the primary key and all keys contains
1106
1051
            the primary key, then we can use any key to find this column
1107
1052
          */
1108
 
          if (share->storage_engine->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX))
 
1053
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1109
1054
          {
1110
1055
            field->part_of_key= share->keys_in_use;
1111
1056
            if (field->part_of_sortkey.test(key))
1122
1067
      set_if_bigger(share->max_key_length,keyinfo->key_length+
1123
1068
                    keyinfo->key_parts);
1124
1069
      share->total_key_length+= keyinfo->key_length;
1125
 
 
1126
 
      if (keyinfo->flags & HA_NOSAME)
1127
 
      {
 
1070
      /*
 
1071
        MERGE tables do not have unique indexes. But every key could be
 
1072
        an unique index on the underlying MyISAM table. (Bug #10400)
 
1073
      */
 
1074
      if ((keyinfo->flags & HA_NOSAME) ||
 
1075
          (ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1128
1076
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
1129
 
      }
1130
1077
    }
1131
1078
    if (primary_key < MAX_KEY &&
1132
 
        (share->keys_in_use.test(primary_key)))
 
1079
        (share->keys_in_use.test(primary_key)))
1133
1080
    {
1134
1081
      share->primary_key= primary_key;
1135
1082
      /*
1136
 
        If we are using an integer as the primary key then allow the user to
1137
 
        refer to it as '_rowid'
 
1083
        If we are using an integer as the primary key then allow the user to
 
1084
        refer to it as '_rowid'
1138
1085
      */
1139
1086
      if (share->key_info[primary_key].key_parts == 1)
1140
1087
      {
1141
 
        Field *field= share->key_info[primary_key].key_part[0].field;
1142
 
        if (field && field->result_type() == INT_RESULT)
 
1088
        Field *field= share->key_info[primary_key].key_part[0].field;
 
1089
        if (field && field->result_type() == INT_RESULT)
1143
1090
        {
1144
1091
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
1145
 
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
 
1092
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1146
1093
                                      fieldnr);
1147
1094
        }
1148
1095
      }
 
1096
 
1149
1097
    }
1150
1098
    else
1151
1099
      share->primary_key = MAX_KEY; // we do not have a primary key
1183
1131
    for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
1184
1132
    {
1185
1133
      if ((*ptr)->flags & BLOB_FLAG)
1186
 
        (*save++)= k;
 
1134
        (*save++)= k;
1187
1135
    }
1188
1136
  }
1189
1137
 
1190
 
  share->db_low_byte_first= true; // @todo Question this.
 
1138
  share->db_low_byte_first= handler_file->low_byte_first();
1191
1139
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1192
1140
 
1193
1141
  my_bitmap_map *bitmaps;
1198
1146
  share->all_set.init(bitmaps, share->fields);
1199
1147
  share->all_set.setAll();
1200
1148
 
 
1149
  if (handler_file)
 
1150
    delete handler_file;
1201
1151
  return (0);
1202
1152
 
1203
1153
err:
1204
 
  if (field_offsets)
1205
 
    free(field_offsets);
1206
 
  if (field_pack_length)
1207
 
    free(field_pack_length);
1208
 
 
1209
1154
  share->error= error;
1210
 
  share->open_errno= errno;
 
1155
  share->open_errno= my_errno;
1211
1156
  share->errarg= 0;
1212
1157
  hash_free(&share->name_hash);
 
1158
  if (handler_file)
 
1159
    delete handler_file;
1213
1160
  share->open_table_error(error, share->open_errno, 0);
1214
1161
 
1215
1162
  return error;
1216
1163
}
1217
1164
 
1218
1165
/*
1219
 
  Read table definition from a binary / text based .frm cursor
 
1166
  Read table definition from a binary / text based .frm file
1220
1167
 
1221
1168
  SYNOPSIS
1222
1169
  open_table_def()
1223
 
  session               Thread Cursor
 
1170
  session               Thread handler
1224
1171
  share         Fill this with table definition
1225
1172
 
1226
1173
  NOTES
1233
1180
   0    ok
1234
1181
   1    Error (see open_table_error)
1235
1182
   2    Error (see open_table_error)
1236
 
   3    Wrong data in .frm cursor
 
1183
   3    Wrong data in .frm file
1237
1184
   4    Error (see open_table_error)
1238
1185
   5    Error (see open_table_error: charset unavailable)
1239
1186
   6    Unknown .frm version
1240
1187
*/
1241
1188
 
1242
 
int open_table_def(Session& session, TableIdentifier &identifier, TableShare *share)
 
1189
int open_table_def(Session *session, TableShare *share)
1243
1190
{
1244
1191
  int error;
1245
1192
  bool error_given;
1249
1196
 
1250
1197
  message::Table table;
1251
1198
 
1252
 
  error= plugin::StorageEngine::getTableDefinition(session, identifier, table);
 
1199
  error= StorageEngine::getTableProto(share->normalized_path.str, &table);
1253
1200
 
1254
1201
  if (error != EEXIST)
1255
1202
  {
1256
 
    if (error > 0)
 
1203
    if (error>0)
1257
1204
    {
1258
 
      errno= error;
 
1205
      my_errno= error;
1259
1206
      error= 1;
1260
1207
    }
1261
1208
    else
1262
1209
    {
1263
 
      if (not table.IsInitialized())
 
1210
      if (!table.IsInitialized())
1264
1211
      {
1265
1212
        error= 4;
1266
1213
      }
1270
1217
 
1271
1218
  error= parse_table_proto(session, table, share);
1272
1219
 
1273
 
  share->table_category= TABLE_CATEGORY_USER;
 
1220
  share->table_category= get_table_category(& share->db);
 
1221
 
 
1222
  if (!error)
 
1223
    session->status_var.opened_shares++;
1274
1224
 
1275
1225
err_not_open:
1276
1226
  if (error && !error_given)
1277
1227
  {
1278
1228
    share->error= error;
1279
 
    share->open_table_error(error, (share->open_errno= errno), 0);
 
1229
    share->open_table_error(error, (share->open_errno= my_errno), 0);
1280
1230
  }
1281
1231
 
1282
1232
  return(error);
1288
1238
 
1289
1239
  SYNOPSIS
1290
1240
    open_table_from_share()
1291
 
    session                     Thread Cursor
 
1241
    session                     Thread handler
1292
1242
    share               Table definition
1293
1243
    alias               Alias for table
1294
1244
    db_stat             open flags (for example HA_OPEN_KEYFILE|
1295
1245
                        HA_OPEN_RNDFILE..) can be 0 (example in
1296
1246
                        ha_example_table)
 
1247
    prgflag             READ_ALL etc..
1297
1248
    ha_open_flags       HA_OPEN_ABORT_IF_LOCKED etc..
1298
1249
    outparam            result table
 
1250
    open_mode           One of OTM_OPEN|OTM_CREATE|OTM_ALTER
 
1251
                        if OTM_CREATE some errors are ignore
 
1252
                        if OTM_ALTER HA_OPEN is not called
1299
1253
 
1300
1254
  RETURN VALUES
1301
1255
   0    ok
1302
1256
   1    Error (see open_table_error)
1303
1257
   2    Error (see open_table_error)
1304
 
   3    Wrong data in .frm cursor
 
1258
   3    Wrong data in .frm file
1305
1259
   4    Error (see open_table_error)
1306
1260
   5    Error (see open_table_error: charset unavailable)
1307
1261
   7    Table definition has changed in engine
1308
1262
*/
1309
1263
 
1310
1264
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)
 
1265
                          uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
 
1266
                          Table *outparam, open_table_mode open_mode)
1313
1267
{
1314
1268
  int error;
1315
1269
  uint32_t records, i, bitmap_size;
1324
1278
  outparam->resetTable(session, share, db_stat);
1325
1279
 
1326
1280
 
1327
 
  if (not (outparam->alias= strdup(alias)))
 
1281
  if (!(outparam->alias= strdup(alias)))
1328
1282
    goto err;
1329
1283
 
1330
 
  /* Allocate Cursor */
1331
 
  if (not (outparam->cursor= share->db_type()->getCursor(*share, &outparam->mem_root)))
1332
 
    goto err;
 
1284
  /* Allocate handler */
 
1285
  if (!(prgflag & OPEN_FRM_FILE_ONLY))
 
1286
  {
 
1287
    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
 
1288
                                          share->db_type())))
 
1289
      goto err;
 
1290
  }
 
1291
  else
 
1292
  {
 
1293
    assert(!db_stat);
 
1294
  }
1333
1295
 
1334
1296
  error= 4;
1335
1297
  records= 0;
1336
 
  if ((db_stat & HA_OPEN_KEYFILE))
 
1298
  if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1337
1299
    records=1;
1338
 
 
1339
 
  records++;
 
1300
  if (prgflag & (READ_ALL+EXTRA_RECORD))
 
1301
    records++;
1340
1302
 
1341
1303
  if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1342
1304
                                   share->rec_buff_length * records)))
1343
 
    goto err;
 
1305
    goto err;                                   /* purecov: inspected */
1344
1306
 
1345
1307
  if (records == 0)
1346
1308
  {
1374
1336
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1375
1337
                                          (uint32_t) ((share->fields+1)*
1376
1338
                                                  sizeof(Field*)))))
1377
 
    goto err;
 
1339
    goto err;                                   /* purecov: inspected */
1378
1340
 
1379
1341
  outparam->field= field_ptr;
1380
1342
 
1455
1417
 
1456
1418
  /* The table struct is now initialized;  Open the table */
1457
1419
  error= 2;
1458
 
  if (db_stat)
 
1420
  if (db_stat && open_mode != OTM_ALTER)
1459
1421
  {
1460
1422
    int ha_err;
1461
 
    if ((ha_err= (outparam->cursor->
 
1423
    if ((ha_err= (outparam->file->
1462
1424
                  ha_open(outparam, share->normalized_path.str,
1463
1425
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1464
1426
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1467
1429
                          HA_OPEN_ABORT_IF_LOCKED :
1468
1430
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1469
1431
    {
 
1432
      /* Set a flag if the table is crashed and it can be auto. repaired */
 
1433
      share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
 
1434
                       outparam->file->auto_repair() &&
 
1435
                       !(ha_open_flags & HA_OPEN_FOR_REPAIR));
 
1436
 
1470
1437
      switch (ha_err)
1471
1438
      {
1472
1439
        case HA_ERR_NO_SUCH_TABLE:
1473
1440
          /*
1474
1441
            The table did not exists in storage engine, use same error message
1475
 
            as if the .frm cursor didn't exist
 
1442
            as if the .frm file didn't exist
1476
1443
          */
1477
1444
          error= 1;
1478
 
          errno= ENOENT;
 
1445
          my_errno= ENOENT;
1479
1446
          break;
1480
1447
        case EMFILE:
1481
1448
          /*
1482
1449
            Too many files opened, use same error message as if the .frm
1483
 
            cursor can't open
 
1450
            file can't open
1484
1451
           */
1485
1452
          error= 1;
1486
 
          errno= EMFILE;
 
1453
          my_errno= EMFILE;
1487
1454
          break;
1488
1455
        default:
1489
 
          outparam->print_error(ha_err, MYF(0));
 
1456
          outparam->file->print_error(ha_err, MYF(0));
1490
1457
          error_reported= true;
1491
1458
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1492
1459
            error= 7;
1493
1460
          break;
1494
1461
      }
1495
 
      goto err;
 
1462
      goto err;                                 /* purecov: inspected */
1496
1463
    }
1497
1464
  }
1498
1465
 
1500
1467
  memset(bitmaps, 0, bitmap_size*3);
1501
1468
#endif
1502
1469
 
1503
 
  return 0;
 
1470
  session->status_var.opened_tables++;
 
1471
 
 
1472
  return (0);
1504
1473
 
1505
1474
 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
 
1475
  if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
 
1476
    share->open_table_error(error, my_errno, 0);
 
1477
  delete outparam->file;
 
1478
  outparam->file= 0;                            // For easier error checking
1510
1479
  outparam->db_stat= 0;
1511
1480
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on zeroed root
1512
1481
  free((char*) outparam->alias);
1513
1482
  return (error);
1514
1483
}
1515
1484
 
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
 
}
 
1485
/*
 
1486
  Free information allocated by openfrm
 
1487
 
 
1488
  SYNOPSIS
 
1489
    closefrm()
 
1490
    table               Table object to free
 
1491
    free_share          Is 1 if we also want to free table_share
 
1492
*/
1530
1493
 
1531
1494
int Table::closefrm(bool free_share)
1532
1495
{
1533
1496
  int error= 0;
1534
1497
 
1535
1498
  if (db_stat)
1536
 
    error= cursor->close();
 
1499
    error= file->close();
1537
1500
  free((char*) alias);
1538
1501
  alias= NULL;
1539
1502
  if (field)
1542
1505
      delete *ptr;
1543
1506
    field= 0;
1544
1507
  }
1545
 
  delete cursor;
1546
 
  cursor= 0;                            /* For easier errorchecking */
 
1508
  delete file;
 
1509
  file= 0;                              /* For easier errorchecking */
1547
1510
  if (free_share)
1548
1511
  {
1549
 
    if (s->tmp_table == message::Table::STANDARD)
 
1512
    if (s->tmp_table == NO_TMP_TABLE)
1550
1513
      TableShare::release(s);
1551
1514
    else
1552
1515
      s->free_table_share();
1557
1520
}
1558
1521
 
1559
1522
 
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
1523
/* Deallocate temporary blob storage */
1649
1524
 
1650
1525
void free_blobs(register Table *table)
1657
1532
}
1658
1533
 
1659
1534
 
1660
 
        /* error message when opening a form cursor */
 
1535
        /* error message when opening a form file */
1661
1536
 
1662
1537
void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
1663
1538
{
1672
1547
      my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str);
1673
1548
    else
1674
1549
    {
1675
 
      snprintf(buff, sizeof(buff), "%s",normalized_path.str);
 
1550
      sprintf(buff,"%s",normalized_path.str);
1676
1551
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1677
1552
               errortype, buff, db_errno);
1678
1553
    }
1679
1554
    break;
1680
1555
  case 2:
1681
1556
  {
1682
 
    Cursor *cursor= 0;
 
1557
    handler *file= 0;
1683
1558
    const char *datext= "";
1684
1559
 
1685
1560
    if (db_type() != NULL)
1686
1561
    {
1687
 
      if ((cursor= db_type()->getCursor(*this, current_session->mem_root)))
 
1562
      if ((file= get_new_handler(this, current_session->mem_root,
 
1563
                                 db_type())))
1688
1564
      {
1689
1565
        if (!(datext= *db_type()->bas_ext()))
1690
1566
          datext= "";
1692
1568
    }
1693
1569
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1694
1570
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1695
 
    snprintf(buff, sizeof(buff), "%s%s", normalized_path.str,datext);
 
1571
    sprintf(buff,"%s%s", normalized_path.str,datext);
1696
1572
    my_error(err_no,errortype, buff, db_errno);
1697
 
    delete cursor;
 
1573
    delete file;
1698
1574
    break;
1699
1575
  }
1700
1576
  case 5:
1712
1588
    break;
1713
1589
  }
1714
1590
  case 6:
1715
 
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
 
1591
    sprintf(buff,"%s", normalized_path.str);
1716
1592
    my_printf_error(ER_NOT_FORM_FILE,
1717
1593
                    _("Table '%-.64s' was created with a different version "
1718
1594
                    "of Drizzle and cannot be read"),
1722
1598
    break;
1723
1599
  default:                              /* Better wrong error than none */
1724
1600
  case 4:
1725
 
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
 
1601
    sprintf(buff,"%s", normalized_path.str);
1726
1602
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1727
1603
    break;
1728
1604
  }
1730
1606
} /* open_table_error */
1731
1607
 
1732
1608
 
1733
 
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
 
1609
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
1734
1610
{
1735
1611
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
1736
1612
  if (!result)
1866
1742
 
1867
1743
 
1868
1744
 
1869
 
void Table::updateCreateInfo(message::Table *table_proto)
 
1745
void Table::updateCreateInfo(HA_CREATE_INFO *create_info,
 
1746
                             message::Table *table_proto)
1870
1747
{
1871
1748
  message::Table::TableOptions *table_options= table_proto->mutable_options();
1872
 
  table_options->set_block_size(s->block_size);
 
1749
  create_info->table_options= s->db_create_options;
 
1750
  create_info->block_size= s->block_size;
 
1751
  create_info->row_type= s->row_type;
 
1752
  create_info->default_table_charset= s->table_charset;
 
1753
  create_info->table_charset= 0;
1873
1754
  table_options->set_comment(s->getComment());
1874
1755
}
1875
1756
 
1881
1762
  from_s.append(ext);
1882
1763
  to_s.append(to);
1883
1764
  to_s.append(ext);
1884
 
  return (internal::my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
 
1765
  return (my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
1885
1766
}
1886
1767
 
1887
1768
/*
1918
1799
    org_name            Name of database and length
1919
1800
 
1920
1801
  RETURN
1921
 
    false error
1922
 
    true ok
 
1802
    0   ok
 
1803
    1   error
1923
1804
*/
1924
1805
 
1925
 
bool check_db_name(SchemaIdentifier &schema_identifier)
 
1806
bool check_db_name(LEX_STRING *org_name)
1926
1807
{
1927
 
  if (not plugin::Authorization::isAuthorized(current_session->getSecurityContext(), schema_identifier))
1928
 
  {
1929
 
    return false;
1930
 
  }
1931
 
 
1932
 
  return schema_identifier.isValid();
 
1808
  char *name= org_name->str;
 
1809
  uint32_t name_length= org_name->length;
 
1810
 
 
1811
  if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
 
1812
    return 1;
 
1813
 
 
1814
  if (name != any_db)
 
1815
    my_casedn_str(files_charset_info, name);
 
1816
 
 
1817
  return check_identifier_name(org_name);
1933
1818
}
1934
1819
 
 
1820
 
1935
1821
/*
1936
1822
  Allow anything as a table name, as long as it doesn't contain an
1937
1823
  ' ' at the end
2009
1895
 
2010
1896
 
2011
1897
/*
2012
 
  Tell Cursor we are going to call position() and rnd_pos() later.
 
1898
  Tell handler we are going to call position() and rnd_pos() later.
2013
1899
 
2014
1900
  NOTES:
2015
1901
  This is needed for handlers that uses the primary key to find the
2020
1906
void Table::prepare_for_position()
2021
1907
{
2022
1908
 
2023
 
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
 
1909
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
2024
1910
      s->primary_key < MAX_KEY)
2025
1911
  {
2026
1912
    mark_columns_used_by_index_no_reset(s->primary_key);
2043
1929
{
2044
1930
  MyBitmap *bitmap= &tmp_set;
2045
1931
 
2046
 
  (void) cursor->extra(HA_EXTRA_KEYREAD);
 
1932
  (void) file->extra(HA_EXTRA_KEYREAD);
2047
1933
  bitmap->clearAll();
2048
1934
  mark_columns_used_by_index_no_reset(index, bitmap);
2049
1935
  column_bitmaps_set(bitmap, bitmap);
2066
1952
{
2067
1953
 
2068
1954
  key_read= 0;
2069
 
  (void) cursor->extra(HA_EXTRA_NO_KEYREAD);
 
1955
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
2070
1956
  default_column_bitmaps();
2071
1957
  return;
2072
1958
}
2135
2021
void Table::mark_columns_needed_for_delete()
2136
2022
{
2137
2023
  /*
2138
 
    If the Cursor has no cursor capabilites, or we have row-based
 
2024
    If the handler has no cursor capabilites, or we have row-based
2139
2025
    replication active for the current statement, we have to read
2140
2026
    either the primary key, the hidden primary key or all columns to
2141
2027
    be able to do an delete
2151
2037
    mark_columns_used_by_index_no_reset(s->primary_key);
2152
2038
 
2153
2039
  /* If we the engine wants all predicates we mark all keys */
2154
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
2040
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2155
2041
  {
2156
2042
    Field **reg_field;
2157
2043
    for (reg_field= field ; *reg_field ; reg_field++)
2175
2061
    if neeed, either the primary key column or all columns to be read.
2176
2062
    (see mark_columns_needed_for_delete() for details)
2177
2063
 
2178
 
    If the engine has HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
 
2064
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
2179
2065
    mark all USED key columns as 'to-be-read'. This allows the engine to
2180
2066
    loop over the given record to find all changed keys and doesn't have to
2181
2067
    retrieve the row again.
2184
2070
void Table::mark_columns_needed_for_update()
2185
2071
{
2186
2072
  /*
2187
 
    If the Cursor has no cursor capabilites, or we have row-based
 
2073
    If the handler has no cursor capabilites, or we have row-based
2188
2074
    logging active for the current statement, we have to read either
2189
2075
    the primary key, the hidden primary key or all columns to be
2190
2076
    able to do an update
2198
2084
  else
2199
2085
    mark_columns_used_by_index_no_reset(s->primary_key);
2200
2086
 
2201
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
2087
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2202
2088
  {
2203
2089
    /* Mark all used key columns for read */
2204
2090
    Field **reg_field;
2214
2100
 
2215
2101
 
2216
2102
/*
2217
 
  Mark columns the Cursor needs for doing an insert
 
2103
  Mark columns the handler needs for doing an insert
2218
2104
 
2219
2105
  For now, this is used to mark fields used by the trigger
2220
2106
  as changed.
2255
2141
/**
2256
2142
  Create field for temporary table from given field.
2257
2143
 
2258
 
  @param session               Thread Cursor
 
2144
  @param session               Thread handler
2259
2145
  @param org_field    field from which new field will be created
2260
2146
  @param name         New field name
2261
2147
  @param table         Temporary table
2314
2200
 
2315
2201
 
2316
2202
/**
 
2203
  Create field for information schema table.
 
2204
 
 
2205
  @param session                Thread handler
 
2206
  @param table          Temporary table
 
2207
  @param item           Item to create a field for
 
2208
 
 
2209
  @retval
 
2210
    0                   on error
 
2211
  @retval
 
2212
    new_created field
 
2213
*/
 
2214
 
 
2215
static Field *create_tmp_field_for_schema(Item *item, Table *table)
 
2216
{
 
2217
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
 
2218
  {
 
2219
    Field *field;
 
2220
    if (item->max_length > MAX_FIELD_VARCHARLENGTH)
 
2221
      field= new Field_blob(item->max_length, item->maybe_null,
 
2222
                            item->name, item->collation.collation);
 
2223
    else
 
2224
      field= new Field_varstring(item->max_length, item->maybe_null,
 
2225
                                 item->name,
 
2226
                                 table->s, item->collation.collation);
 
2227
    if (field)
 
2228
      field->init(table);
 
2229
    return field;
 
2230
  }
 
2231
  return item->tmp_table_field_from_field_type(table, 0);
 
2232
}
 
2233
 
 
2234
 
 
2235
/**
2317
2236
  Create a temp table according to a field list.
2318
2237
 
2319
2238
  Given field pointers are changed to point at tmp_table for
2343
2262
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
2344
2263
#define RATIO_TO_PACK_ROWS             2
2345
2264
 
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
2265
Table *
2355
2266
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
2356
2267
                 order_st *group, bool distinct, bool save_sum_fields,
2357
2268
                 uint64_t select_options, ha_rows rows_limit,
2358
2269
                 const char *table_alias)
2359
2270
{
2360
 
  memory::Root *mem_root_save, own_root;
 
2271
  MEM_ROOT *mem_root_save, own_root;
2361
2272
  Table *table;
2362
2273
  TableShare *share;
2363
2274
  uint  i,field_count,null_count,null_pack_length;
2366
2277
  uint32_t  blob_count,group_null_items, string_count;
2367
2278
  uint32_t fieldnr= 0;
2368
2279
  ulong reclength, string_total_length;
2369
 
  bool  using_unique_constraint= false;
2370
 
  bool  use_packed_rows= true;
 
2280
  bool  using_unique_constraint= 0;
 
2281
  bool  use_packed_rows= 0;
2371
2282
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
2372
 
  char  *tmpname;
2373
 
  char  path[FN_REFLEN];
 
2283
  char  *tmpname,path[FN_REFLEN];
2374
2284
  unsigned char *pos, *group_buff, *bitmaps;
2375
2285
  unsigned char *null_flags;
2376
2286
  Field **reg_field, **from_field, **default_field;
2386
2296
 
2387
2297
  status_var_increment(session->status_var.created_tmp_tables);
2388
2298
 
2389
 
  make_internal_temporary_table_path(session, path);
 
2299
  /* if we run out of slots or we are not using tempool */
 
2300
  sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
 
2301
          session->thread_id, session->tmp_table++);
 
2302
 
 
2303
  /*
 
2304
    No need to change table name to lower case as we are only creating
 
2305
    MyISAM or HEAP tables here
 
2306
  */
 
2307
  fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
2308
 
2390
2309
 
2391
2310
  if (group)
2392
2311
  {
2393
 
    if (! param->quick_group)
 
2312
    if (!param->quick_group)
2394
2313
      group= 0;                                 // Can't use group key
2395
2314
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
2396
2315
    {
2402
2321
      */
2403
2322
      (*tmp->item)->marker= 4;
2404
2323
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
2405
 
        using_unique_constraint= true;
 
2324
        using_unique_constraint=1;
2406
2325
    }
2407
2326
    if (param->group_length >= MAX_BLOB_WIDTH)
2408
 
      using_unique_constraint= true;
 
2327
      using_unique_constraint=1;
2409
2328
    if (group)
2410
2329
      distinct= 0;                              // Can't use distinct
2411
2330
  }
2423
2342
  if (param->precomputed_group_by)
2424
2343
    copy_func_count+= param->sum_func_count;
2425
2344
 
2426
 
  memory::init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
2345
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
2427
2346
 
2428
2347
  if (!multi_alloc_root(&own_root,
2429
2348
                        &table, sizeof(*table),
2444
2363
                        &bitmaps, bitmap_buffer_size(field_count)*2,
2445
2364
                        NULL))
2446
2365
  {
2447
 
    return NULL;
 
2366
    return NULL;                                /* purecov: inspected */
2448
2367
  }
2449
2368
  /* CopyField belongs to Tmp_Table_Param, allocate it in Session mem_root */
2450
2369
  if (!(param->copy_field= copy= new (session->mem_root) CopyField[field_count]))
2451
2370
  {
2452
 
    free_root(&own_root, MYF(0));
2453
 
    return NULL;
 
2371
    free_root(&own_root, MYF(0));               /* purecov: inspected */
 
2372
    return NULL;                                /* purecov: inspected */
2454
2373
  }
2455
2374
  param->items_to_copy= copy_func;
2456
2375
  strcpy(tmpname,path);
2532
2451
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
2533
2452
                             tmp_from_field, &default_field[fieldnr],
2534
2453
                             group != 0,not_all_columns,
2535
 
                             false,
 
2454
                             distinct, 0,
2536
2455
                             param->convert_blob_length);
2537
2456
          if (!new_field)
2538
2457
            goto err;                                   // Should be OOM
2577
2496
        We here distinguish between UNION and multi-table-updates by the fact
2578
2497
        that in the later case group is set to the row pointer.
2579
2498
      */
2580
 
      Field *new_field=
 
2499
      Field *new_field= (param->schema_table) ?
 
2500
        create_tmp_field_for_schema(item, table) :
2581
2501
        create_tmp_field(session, table, item, type, &copy_func,
2582
2502
                         tmp_from_field, &default_field[fieldnr],
2583
2503
                         group != 0,
2584
2504
                         !force_copy_fields &&
2585
2505
                           (not_all_columns || group != 0),
 
2506
                         /*
 
2507
                           If item->marker == 4 then we force create_tmp_field
 
2508
                           to create a 64-bit longs for BIT fields because HEAP
 
2509
                           tables can't index BIT fields directly. We do the same
 
2510
                           for distinct, as we want the distinct index to be
 
2511
                           usable in this case too.
 
2512
                         */
 
2513
                         item->marker == 4 || param->bit_fields_as_long,
2586
2514
                         force_copy_fields,
2587
2515
                         param->convert_blob_length);
2588
2516
 
2636
2564
  /* If result table is small; use a heap */
2637
2565
  /* future: storage engine selection can be made dynamic? */
2638
2566
  if (blob_count || using_unique_constraint ||
2639
 
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
 
2567
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
2568
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
2640
2569
  {
2641
2570
    share->storage_engine= myisam_engine;
2642
 
    table->cursor= share->db_type()->getCursor(*share, &table->mem_root);
 
2571
    table->file= get_new_handler(share, &table->mem_root,
 
2572
                                 share->db_type());
2643
2573
    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;
 
2574
        (param->group_parts > table->file->max_key_parts() ||
 
2575
         param->group_length > table->file->max_key_length()))
 
2576
      using_unique_constraint=1;
2647
2577
  }
2648
2578
  else
2649
2579
  {
2650
2580
    share->storage_engine= heap_engine;
2651
 
    table->cursor= share->db_type()->getCursor(*share, &table->mem_root);
 
2581
    table->file= get_new_handler(share, &table->mem_root,
 
2582
                                 share->db_type());
2652
2583
  }
2653
 
  if (! table->cursor)
 
2584
  if (!table->file)
2654
2585
    goto err;
2655
2586
 
2656
2587
 
2657
 
  if (! using_unique_constraint)
 
2588
  if (!using_unique_constraint)
2658
2589
    reclength+= group_null_items;       // null flag is stored separately
2659
2590
 
2660
2591
  share->blob_fields= blob_count;
2752
2683
         inherit the default value that is defined for the field referred
2753
2684
         by the Item_field object from which 'field' has been created.
2754
2685
      */
2755
 
      ptrdiff_t diff;
 
2686
      my_ptrdiff_t diff;
2756
2687
      Field *orig_field= default_field[i];
2757
2688
      /* Get the value from default_values */
2758
 
      diff= (ptrdiff_t) (orig_field->table->s->default_values-
 
2689
      diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
2759
2690
                            orig_field->table->record[0]);
2760
2691
      orig_field->move_field_offset(diff);      // Points now at default_values
2761
2692
      if (orig_field->is_real_null())
2839
2770
      key_part_info->offset= field->offset(table->record[0]);
2840
2771
      key_part_info->length= (uint16_t) field->key_length();
2841
2772
      key_part_info->type=   (uint8_t) field->key_type();
2842
 
      key_part_info->key_type= 
 
2773
      key_part_info->key_type =
2843
2774
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
2844
2775
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
2845
2776
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
2846
 
        0 : 1;
 
2777
        0 : FIELDFLAG_BINARY;
2847
2778
      if (!using_unique_constraint)
2848
2779
      {
2849
2780
        cur_group->buff=(char*) group_buff;
2852
2783
                                                     test(maybe_null),
2853
2784
                                                     field->null_ptr,
2854
2785
                                                     field->null_bit)))
2855
 
          goto err;
 
2786
          goto err; /* purecov: inspected */
2856
2787
        if (maybe_null)
2857
2788
        {
2858
2789
          /*
2926
2857
                                                0,
2927
2858
                                                (unsigned char*) 0,
2928
2859
                                                (uint32_t) 0,
 
2860
                                                Field::NONE,
2929
2861
                                                NULL,
2930
2862
                                                table->s,
2931
2863
                                                &my_charset_bin);
2932
2864
      if (!key_part_info->field)
2933
2865
        goto err;
2934
2866
      key_part_info->field->init(table);
2935
 
      key_part_info->key_type= 1; /* binary comparison */
 
2867
      key_part_info->key_type=FIELDFLAG_BINARY;
2936
2868
      key_part_info->type=    HA_KEYTYPE_BINARY;
2937
2869
      key_part_info++;
2938
2870
    }
2947
2879
      key_part_info->length=   (uint16_t) (*reg_field)->pack_length();
2948
2880
      /* TODO:
2949
2881
        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.
 
2882
        key part is a copy/paste from opt_range.cc, and table.cc.
2951
2883
        This should be factored out, e.g. as a method of Field.
2952
2884
        In addition it is not clear if any of the Field::*_length
2953
2885
        methods is supposed to compute the same length. If so, it
2966
2898
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
2967
2899
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
2968
2900
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
2969
 
        0 : 1;
 
2901
        0 : FIELDFLAG_BINARY;
2970
2902
    }
2971
2903
  }
2972
2904
 
2973
2905
  if (session->is_fatal_error)                          // If end of memory
2974
 
    goto err;
 
2906
    goto err;                                    /* purecov: inspected */
2975
2907
  share->db_record_offset= 1;
2976
2908
  if (share->db_type() == myisam_engine)
2977
2909
  {
2988
2920
 
2989
2921
err:
2990
2922
  session->mem_root= mem_root_save;
2991
 
  table->free_tmp_table(session);
2992
 
  return NULL;
 
2923
  table->free_tmp_table(session);                    /* purecov: inspected */
 
2924
  return NULL;                          /* purecov: inspected */
2993
2925
}
2994
2926
 
2995
2927
/****************************************************************************/
2998
2930
  Create a reduced Table object with properly set up Field list from a
2999
2931
  list of field definitions.
3000
2932
 
3001
 
    The created table doesn't have a table Cursor associated with
 
2933
    The created table doesn't have a table handler associated with
3002
2934
    it, has no keys, no group/distinct, no copy_funcs array.
3003
2935
    The sole purpose of this Table object is to use the power of Field
3004
2936
    class to read/write data to/from table->record[0]. Then one can store
3049
2981
  List_iterator_fast<CreateField> it(field_list);
3050
2982
  while ((cdef= it++))
3051
2983
  {
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,
 
2984
    *field= make_field(share, NULL, 0, cdef->length,
 
2985
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
 
2986
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
 
2987
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
3062
2988
                       cdef->unireg_check,
3063
 
                       cdef->interval,
3064
 
                       cdef->field_name);
 
2989
                       cdef->interval, cdef->field_name);
3065
2990
    if (!*field)
3066
2991
      goto error;
3067
2992
    (*field)->init(table);
3129
3054
bool Table::open_tmp_table()
3130
3055
{
3131
3056
  int error;
3132
 
  if ((error=cursor->ha_open(this, s->table_name.str,O_RDWR,
 
3057
  if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
3133
3058
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
3134
3059
  {
3135
 
    print_error(error, MYF(0));
 
3060
    file->print_error(error,MYF(0)); /* purecov: inspected */
3136
3061
    db_stat= 0;
3137
3062
    return true;
3138
3063
  }
3139
 
  (void) cursor->extra(HA_EXTRA_QUICK);         /* Faster */
 
3064
  (void) file->extra(HA_EXTRA_QUICK);           /* Faster */
3140
3065
  return false;
3141
3066
}
3142
3067
 
3182
3107
 
3183
3108
  if (share->keys)
3184
3109
  {                                             // Get keys for ni_create
3185
 
    bool using_unique_constraint= false;
 
3110
    bool using_unique_constraint= 0;
3186
3111
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
3187
3112
                                            sizeof(*seg) * keyinfo->key_parts);
3188
3113
    if (!seg)
3189
3114
      goto err;
3190
3115
 
3191
3116
    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() ||
 
3117
    if (keyinfo->key_length >= file->max_key_length() ||
 
3118
        keyinfo->key_parts > file->max_key_parts() ||
3194
3119
        share->uniques)
3195
3120
    {
3196
3121
      /* Can't create a key; Make a unique constraint instead of a key */
3197
3122
      share->keys=    0;
3198
3123
      share->uniques= 1;
3199
 
      using_unique_constraint= true;
 
3124
      using_unique_constraint=1;
3200
3125
      memset(&uniquedef, 0, sizeof(uniquedef));
3201
3126
      uniquedef.keysegs=keyinfo->key_parts;
3202
3127
      uniquedef.seg=seg;
3226
3151
      seg->start=    keyinfo->key_part[i].offset;
3227
3152
      if (key_field->flags & BLOB_FLAG)
3228
3153
      {
3229
 
        seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
 
3154
        seg->type=
 
3155
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
3230
3156
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
3231
3157
        seg->bit_start= (uint8_t)(key_field->pack_length()
3232
3158
                                  - share->blob_ptr_size);
3246
3172
          In this case we have to tell MyISAM that two NULL should
3247
3173
          on INSERT be regarded at the same value
3248
3174
        */
3249
 
        if (! using_unique_constraint)
 
3175
        if (!using_unique_constraint)
3250
3176
          keydef.flag|= HA_NULL_ARE_EQUAL;
3251
3177
      }
3252
3178
    }
3265
3191
                       &create_info,
3266
3192
                       HA_CREATE_TMP_TABLE)))
3267
3193
  {
3268
 
    print_error(error, MYF(0));
 
3194
    file->print_error(error,MYF(0));    /* purecov: inspected */
3269
3195
    db_stat= 0;
3270
3196
    goto err;
3271
3197
  }
3279
3205
 
3280
3206
void Table::free_tmp_table(Session *session)
3281
3207
{
3282
 
  memory::Root own_root= mem_root;
 
3208
  MEM_ROOT own_root= mem_root;
3283
3209
  const char *save_proc_info;
3284
3210
 
3285
3211
  save_proc_info=session->get_proc_info();
3286
3212
  session->set_proc_info("removing tmp table");
3287
3213
 
3288
3214
  // Release latches since this can take a long time
3289
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
3215
  ha_release_temporary_latches(session);
3290
3216
 
3291
 
  if (cursor)
 
3217
  if (file)
3292
3218
  {
3293
3219
    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;
 
3220
      file->ha_drop_table(s->table_name.str);
 
3221
    else
 
3222
      s->db_type()->deleteTable(session, s->table_name.str);
 
3223
    delete file;
3300
3224
  }
3301
3225
 
3302
3226
  /* free blobs */
3326
3250
  if (table->s->db_type() != heap_engine ||
3327
3251
      error != HA_ERR_RECORD_FILE_FULL)
3328
3252
  {
3329
 
    table->print_error(error, MYF(0));
 
3253
    table->file->print_error(error,MYF(0));
3330
3254
    return true;
3331
3255
  }
3332
3256
 
3333
3257
  // Release latches since this can take a long time
3334
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
3258
  ha_release_temporary_latches(session);
3335
3259
 
3336
3260
  new_table= *table;
3337
3261
  share= *table->s;
3338
3262
  new_table.s= &share;
3339
3263
  new_table.s->storage_engine= myisam_engine;
3340
 
  if (not (new_table.cursor= new_table.s->db_type()->getCursor(share, &new_table.mem_root)))
 
3264
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
 
3265
                                        new_table.s->db_type())))
3341
3266
    return true;                                // End of memory
3342
3267
 
3343
3268
  save_proc_info=session->get_proc_info();
3349
3274
    goto err2;
3350
3275
  if (new_table.open_tmp_table())
3351
3276
    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);
 
3277
  if (table->file->indexes_are_disabled())
 
3278
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
 
3279
  table->file->ha_index_or_rnd_end();
 
3280
  table->file->ha_rnd_init(1);
3356
3281
  if (table->no_rows)
3357
3282
  {
3358
 
    new_table.cursor->extra(HA_EXTRA_NO_ROWS);
 
3283
    new_table.file->extra(HA_EXTRA_NO_ROWS);
3359
3284
    new_table.no_rows=1;
3360
3285
  }
3361
3286
 
3362
3287
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
3363
 
  new_table.cursor->extra(HA_EXTRA_WRITE_CACHE);
 
3288
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
3364
3289
 
3365
3290
  /*
3366
3291
    copy all old rows from heap table to MyISAM table
3367
3292
    This is the only code that uses record[1] to read/write but this
3368
3293
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
3369
3294
  */
3370
 
  while (!table->cursor->rnd_next(new_table.record[1]))
 
3295
  while (!table->file->rnd_next(new_table.record[1]))
3371
3296
  {
3372
 
    write_err= new_table.cursor->ha_write_row(new_table.record[1]);
 
3297
    write_err= new_table.file->ha_write_row(new_table.record[1]);
3373
3298
    if (write_err)
3374
3299
      goto err;
3375
3300
  }
3376
3301
  /* copy row that filled HEAP table */
3377
 
  if ((write_err=new_table.cursor->ha_write_row(table->record[0])))
 
3302
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
3378
3303
  {
3379
 
    if (new_table.cursor->is_fatal_error(write_err, HA_CHECK_DUP) ||
 
3304
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
3380
3305
        !ignore_last_dupp_key_error)
3381
3306
      goto err;
3382
3307
  }
3383
3308
 
3384
3309
  /* 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;
 
3310
  (void) table->file->ha_rnd_end();
 
3311
  (void) table->file->close();                  // This deletes the table !
 
3312
  delete table->file;
 
3313
  table->file= NULL;
3389
3314
  new_table.s= table->s;                       // Keep old share
3390
3315
  *table= new_table;
3391
3316
  *table->s= share;
3392
3317
 
3393
 
  table->cursor->change_table_ptr(table, table->s);
 
3318
  table->file->change_table_ptr(table, table->s);
3394
3319
  table->use_all_columns();
3395
3320
  if (save_proc_info)
3396
3321
  {
3402
3327
  return false;
3403
3328
 
3404
3329
 err:
3405
 
  table->print_error(write_err, MYF(0));
3406
 
  (void) table->cursor->ha_rnd_end();
3407
 
  (void) new_table.cursor->close();
3408
 
 
 
3330
  table->file->print_error(write_err, MYF(0));
 
3331
  (void) table->file->ha_rnd_end();
 
3332
  (void) new_table.file->close();
3409
3333
 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
 
 
 
3334
  new_table.s->db_type()->deleteTable(session, new_table.s->table_name.str);
3415
3335
 err2:
3416
 
  delete new_table.cursor;
 
3336
  delete new_table.file;
3417
3337
  session->set_proc_info(save_proc_info);
3418
3338
  table->mem_root= new_table.mem_root;
3419
3339
  return true;
3476
3396
{
3477
3397
  if (s->blob_fields + s->varchar_fields == 0)
3478
3398
    return memcmp(this->record[0], this->record[1], (size_t) s->reclength);
3479
 
  
3480
3399
  /* 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
 
 
 
3400
  if (memcmp(null_flags,
 
3401
             null_flags + s->rec_buff_length,
 
3402
             s->null_bytes))
 
3403
    return true;                                // Diff in NULL value
3484
3404
  /* Compare updated fields */
3485
3405
  for (Field **ptr= field ; *ptr ; ptr++)
3486
3406
  {
3546
3466
  memset(null_flags, 255, s->null_bytes);
3547
3467
}
3548
3468
 
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
3469
/*****************************************************************************
3618
3470
  The different ways to read a record
3619
3471
  Returns -1 if row was not found, 0 if row was found and 1 on errors
3620
3472
*****************************************************************************/
3621
3473
 
3622
 
/** Help function when we get some an error from the table Cursor. */
 
3474
/** Help function when we get some an error from the table handler. */
3623
3475
 
3624
3476
int Table::report_error(int error)
3625
3477
{
3635
3487
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
3636
3488
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
3637
3489
                    error, s->path.str);
3638
 
  print_error(error, MYF(0));
 
3490
  file->print_error(error,MYF(0));
3639
3491
 
3640
3492
  return 1;
3641
3493
}
3661
3513
  merge_keys.reset();
3662
3514
}
3663
3515
 
 
3516
Field *Table::find_field_in_table_sef(const char *name)
 
3517
{
 
3518
  Field **field_ptr;
 
3519
  if (s->name_hash.records)
 
3520
  {
 
3521
    field_ptr= (Field**)hash_search(&s->name_hash,(unsigned char*) name,
 
3522
                                    strlen(name));
 
3523
    if (field_ptr)
 
3524
    {
 
3525
      /*
 
3526
        field_ptr points to field in TableShare. Convert it to the matching
 
3527
        field in table
 
3528
      */
 
3529
      field_ptr= (field + (field_ptr - s->field));
 
3530
    }
 
3531
  }
 
3532
  else
 
3533
  {
 
3534
    if (!(field_ptr= field))
 
3535
      return (Field *)0;
 
3536
    for (; *field_ptr; ++field_ptr)
 
3537
      if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
 
3538
        break;
 
3539
  }
 
3540
  if (field_ptr)
 
3541
    return *field_ptr;
 
3542
  else
 
3543
    return (Field *)0;
 
3544
}
 
3545
 
3664
3546
 
3665
3547
/*
3666
3548
  Used by ALTER Table when the table is a temporary one. It changes something
3670
3552
  session->slave_proxy_id, separated by '\0'.
3671
3553
*/
3672
3554
 
3673
 
bool Table::renameAlterTemporaryTable(TableIdentifier &identifier)
 
3555
bool Table::rename_temporary_table(const char *db, const char *table_name)
3674
3556
{
3675
3557
  char *key;
3676
3558
  uint32_t key_length;
3677
3559
  TableShare *share= s;
3678
3560
 
3679
 
  if (not (key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH)))
3680
 
    return true;
 
3561
  if (!(key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH)))
 
3562
    return true;                                /* purecov: inspected */
3681
3563
 
3682
 
  key_length= TableShare::createKey(key, identifier);
 
3564
  key_length= TableShare::createKey(key, db, table_name);
3683
3565
  share->set_table_cache_key(key, key_length);
3684
3566
 
3685
 
  message::Table *message= share->getTableProto();
3686
 
 
3687
 
  message->set_name(identifier.getTableName());
3688
 
  message->set_schema(identifier.getSchemaName());
3689
 
 
3690
3567
  return false;
3691
3568
}
3692
3569
 
3693
 
} /* namespace drizzled */
 
3570
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
3571
template class List<String>;
 
3572
template class List_iterator<String>;
 
3573
#endif