~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: lbieber
  • Date: 2010-10-02 19:48:35 UTC
  • mfrom: (1730.6.19 drizzle-make-lcov)
  • Revision ID: lbieber@orisndriz08-20101002194835-q5zd9qc4lvx1xnfo
Merge Hartmut - clean up lex, now require flex to build, also "make lcov" improvements

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
17
/* Some general useful functions */
46
46
#include "drizzled/charset.h"
47
47
#include "drizzled/internal/m_string.h"
48
48
#include "plugin/myisam/myisam.h"
49
 
#include "drizzled/plugin/storage_engine.h"
50
49
 
51
50
#include <drizzled/item/string.h>
52
51
#include <drizzled/item/int.h>
55
54
#include <drizzled/item/null.h>
56
55
#include <drizzled/temporal.h>
57
56
 
58
 
#include <drizzled/refresh_version.h>
59
 
 
60
 
#include "drizzled/table/singular.h"
 
57
#include "drizzled/table_share_instance.h"
61
58
 
62
59
#include "drizzled/table_proto.h"
63
60
 
66
63
namespace drizzled
67
64
{
68
65
 
 
66
extern pid_t current_pid;
69
67
extern plugin::StorageEngine *heap_engine;
70
68
extern plugin::StorageEngine *myisam_engine;
71
69
 
72
70
/* Functions defined in this cursor */
73
71
 
 
72
void open_table_error(TableShare *share, int error, int db_errno,
 
73
                      myf errortype, int errarg);
 
74
 
74
75
/*************************************************************************/
75
76
 
76
77
// @note this should all be the destructor
80
81
 
81
82
  if (db_stat)
82
83
    error= cursor->close();
83
 
  _alias.clear();
84
 
 
 
84
  free((char*) alias);
 
85
  alias= NULL;
85
86
  if (field)
86
87
  {
87
88
    for (Field **ptr=field ; *ptr ; ptr++)
95
96
 
96
97
  if (free_share)
97
98
  {
98
 
    release();
 
99
    if (s->getType() == message::Table::STANDARD)
 
100
    {
 
101
      TableShare::release(s);
 
102
    }
 
103
    else
 
104
    {
 
105
      delete s;
 
106
    }
 
107
 
 
108
    s= NULL;
99
109
  }
 
110
  mem_root.free_root(MYF(0));
100
111
 
101
112
  return error;
102
113
}
103
114
 
104
 
Table::~Table()
105
 
{
106
 
  mem_root.free_root(MYF(0));
107
 
}
108
 
 
109
115
 
110
116
void Table::resetTable(Session *session,
111
117
                       TableShare *share,
112
118
                       uint32_t db_stat_arg)
113
119
{
114
 
  setShare(share);
115
 
  in_use= session;
116
 
 
 
120
  s= share;
117
121
  field= NULL;
118
122
 
119
123
  cursor= NULL;
126
130
  tablenr= 0;
127
131
  db_stat= db_stat_arg;
128
132
 
 
133
  in_use= session;
129
134
  record[0]= (unsigned char *) NULL;
130
135
  record[1]= (unsigned char *) NULL;
131
136
 
137
142
 
138
143
  pos_in_table_list= NULL;
139
144
  group= NULL;
140
 
  _alias.clear();
 
145
  alias= NULL;
141
146
  null_flags= NULL;
142
147
 
143
148
  lock_position= 0;
248
253
  return (nr);
249
254
} /* set_zone */
250
255
 
 
256
        /* Adjust number to next larger disk buffer */
 
257
 
 
258
ulong next_io_size(register ulong pos)
 
259
{
 
260
  register ulong offset;
 
261
  if ((offset= pos & (IO_SIZE-1)))
 
262
    return pos-offset+IO_SIZE;
 
263
  return pos;
 
264
} /* next_io_size */
 
265
 
251
266
 
252
267
/*
253
268
  Store an SQL quoted string.
311
326
}
312
327
 
313
328
 
 
329
/*
 
330
  Set up column usage bitmaps for a temporary table
 
331
 
 
332
  IMPLEMENTATION
 
333
    For temporary tables, we need one bitmap with all columns set and
 
334
    a tmp_set bitmap to be used by things like filesort.
 
335
*/
 
336
 
 
337
void Table::setup_tmp_table_column_bitmaps(unsigned char *bitmaps)
 
338
{
 
339
  uint32_t field_count= s->sizeFields();
 
340
 
 
341
  this->def_read_set.init((my_bitmap_map*) bitmaps, field_count);
 
342
  this->tmp_set.init((my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count);
 
343
 
 
344
  /* write_set and all_set are copies of read_set */
 
345
  def_write_set= def_read_set;
 
346
  s->all_set= def_read_set;
 
347
  this->getMutableShare()->all_set.setAll();
 
348
  default_column_bitmaps();
 
349
}
 
350
 
 
351
 
314
352
int rename_file_ext(const char * from,const char * to,const char * ext)
315
353
{
316
354
  string from_s, to_s;
334
372
    true ok
335
373
*/
336
374
 
337
 
bool check_db_name(Session *session, identifier::Schema &schema_identifier)
 
375
bool check_db_name(Session *session, SchemaIdentifier &schema_identifier)
338
376
{
339
 
  if (not plugin::Authorization::isAuthorized(session->user(), schema_identifier))
 
377
  if (not plugin::Authorization::isAuthorized(session->getSecurityContext(), schema_identifier))
340
378
  {
341
379
    return false;
342
380
  }
414
452
    bitmap_clear_all(&table->def_read_set);
415
453
    bitmap_clear_all(&table->def_write_set);
416
454
  */
417
 
  def_read_set.reset();
418
 
  def_write_set.reset();
419
 
  column_bitmaps_set(def_read_set, def_write_set);
 
455
  def_read_set.clearAll();
 
456
  def_write_set.clearAll();
 
457
  column_bitmaps_set(&def_read_set, &def_write_set);
420
458
}
421
459
 
422
460
 
433
471
{
434
472
 
435
473
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
436
 
      getShare()->hasPrimaryKey())
 
474
      s->hasPrimaryKey())
437
475
  {
438
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
476
    mark_columns_used_by_index_no_reset(s->getPrimaryKey());
439
477
  }
440
478
  return;
441
479
}
453
491
 
454
492
void Table::mark_columns_used_by_index(uint32_t index)
455
493
{
456
 
  boost::dynamic_bitset<> *bitmap= &tmp_set;
 
494
  MyBitmap *bitmap= &tmp_set;
457
495
 
458
496
  (void) cursor->extra(HA_EXTRA_KEYREAD);
459
 
  bitmap->reset();
460
 
  mark_columns_used_by_index_no_reset(index, *bitmap);
461
 
  column_bitmaps_set(*bitmap, *bitmap);
 
497
  bitmap->clearAll();
 
498
  mark_columns_used_by_index_no_reset(index, bitmap);
 
499
  column_bitmaps_set(bitmap, bitmap);
462
500
  return;
463
501
}
464
502
 
490
528
 
491
529
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
492
530
{
493
 
    mark_columns_used_by_index_no_reset(index, *read_set);
 
531
    mark_columns_used_by_index_no_reset(index, read_set);
494
532
}
495
533
 
496
 
 
497
534
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
498
 
                                                boost::dynamic_bitset<>& bitmap)
 
535
                                                MyBitmap *bitmap)
499
536
{
500
537
  KeyPartInfo *key_part= key_info[index].key_part;
501
 
  KeyPartInfo *key_part_end= (key_part + key_info[index].key_parts);
502
 
  for (; key_part != key_part_end; key_part++)
503
 
  {
504
 
    if (! bitmap.empty())
505
 
      bitmap.set(key_part->fieldnr-1);
506
 
  }
 
538
  KeyPartInfo *key_part_end= (key_part +
 
539
                                key_info[index].key_parts);
 
540
  for (;key_part != key_part_end; key_part++)
 
541
    bitmap->setBit(key_part->fieldnr-1);
507
542
}
508
543
 
509
544
 
522
557
    We must set bit in read set as update_auto_increment() is using the
523
558
    store() to check overflow of auto_increment values
524
559
  */
525
 
  setReadSet(found_next_number_field->position());
526
 
  setWriteSet(found_next_number_field->position());
527
 
  if (getShare()->next_number_keypart)
528
 
    mark_columns_used_by_index_no_reset(getShare()->next_number_index);
 
560
  setReadSet(found_next_number_field->field_index);
 
561
  setWriteSet(found_next_number_field->field_index);
 
562
  if (s->next_number_keypart)
 
563
    mark_columns_used_by_index_no_reset(s->next_number_index);
529
564
}
530
565
 
531
566
 
556
591
    be able to do an delete
557
592
 
558
593
  */
559
 
  if (not getShare()->hasPrimaryKey())
 
594
  if (not s->hasPrimaryKey())
560
595
  {
561
596
    /* fallback to use all columns in the table to identify row */
562
597
    use_all_columns();
563
598
    return;
564
599
  }
565
600
  else
566
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
601
    mark_columns_used_by_index_no_reset(s->getPrimaryKey());
567
602
 
568
603
  /* If we the engine wants all predicates we mark all keys */
569
604
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
572
607
    for (reg_field= field ; *reg_field ; reg_field++)
573
608
    {
574
609
      if ((*reg_field)->flags & PART_KEY_FLAG)
575
 
        setReadSet((*reg_field)->position());
 
610
        setReadSet((*reg_field)->field_index);
576
611
    }
577
612
  }
578
613
}
604
639
    the primary key, the hidden primary key or all columns to be
605
640
    able to do an update
606
641
  */
607
 
  if (not getShare()->hasPrimaryKey())
 
642
  if (not s->hasPrimaryKey())
608
643
  {
609
644
    /* fallback to use all columns in the table to identify row */
610
645
    use_all_columns();
611
646
    return;
612
647
  }
613
648
  else
614
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
649
    mark_columns_used_by_index_no_reset(s->getPrimaryKey());
615
650
 
616
651
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
617
652
  {
621
656
    {
622
657
      /* Merge keys is all keys that had a column refered to in the query */
623
658
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
624
 
        setReadSet((*reg_field)->position());
 
659
        setReadSet((*reg_field)->field_index);
625
660
    }
626
661
  }
627
662
 
659
694
  return length;
660
695
}
661
696
 
662
 
void Table::setVariableWidth(void)
663
 
{
664
 
  assert(in_use);
665
 
  if (in_use && in_use->lex->sql_command == SQLCOM_CREATE_TABLE)
666
 
  {
667
 
    getMutableShare()->setVariableWidth();
668
 
    return;
669
 
  }
670
 
 
671
 
  assert(0); // Programming error, you can't set this on a plain old Table.
672
 
}
673
 
 
674
697
/****************************************************************************
675
698
 Functions for creating temporary tables.
676
699
****************************************************************************/
708
731
  */
709
732
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
710
733
      (org_field->flags & BLOB_FLAG))
711
 
  {
712
 
    table->setVariableWidth();
713
734
    new_field= new Field_varstring(convert_blob_length,
714
735
                                   org_field->maybe_null(),
715
 
                                   org_field->field_name,
 
736
                                   org_field->field_name, table->getMutableShare(),
716
737
                                   org_field->charset());
717
 
  }
718
738
  else
719
 
  {
720
739
    new_field= org_field->new_field(session->mem_root, table,
721
740
                                    table == org_field->getTable());
722
 
  }
723
741
  if (new_field)
724
742
  {
725
743
    new_field->init(table);
772
790
 
773
791
Table *
774
792
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
775
 
                 Order *group, bool distinct, bool save_sum_fields,
 
793
                 order_st *group, bool distinct, bool save_sum_fields,
776
794
                 uint64_t select_options, ha_rows rows_limit,
777
795
                 const char *table_alias)
778
796
{
779
797
  memory::Root *mem_root_save;
 
798
  Table *table;
780
799
  uint  i,field_count,null_count,null_pack_length;
781
800
  uint32_t  copy_func_count= param->func_count;
782
801
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
786
805
  bool  using_unique_constraint= false;
787
806
  bool  use_packed_rows= true;
788
807
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
789
 
  unsigned char *pos, *group_buff;
 
808
  unsigned char *pos, *group_buff, *bitmaps;
790
809
  unsigned char *null_flags;
791
810
  Field **reg_field, **from_field, **default_field;
792
811
  CopyField *copy= 0;
806
825
    {
807
826
      group= 0;                                 // Can't use group key
808
827
    }
809
 
    else for (Order *tmp=group ; tmp ; tmp=tmp->next)
 
828
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
810
829
    {
811
830
      /*
812
831
        marker == 4 means two things:
839
858
    copy_func_count+= param->sum_func_count;
840
859
  }
841
860
 
842
 
  table::Singular *table;
843
 
  table= session->getInstanceTable(); // This will not go into the tableshare cache, so no key is used.
 
861
  TableShareInstance *share= session->getTemporaryShare(message::Table::INTERNAL); // This will not go into the tableshare cache, so no key is used.
844
862
 
845
 
  if (not table->getMemRoot()->multi_alloc_root(0,
 
863
  if (not share->getMemRoot()->multi_alloc_root(0,
846
864
                                                &default_field, sizeof(Field*) * (field_count),
847
865
                                                &from_field, sizeof(Field*)*field_count,
848
866
                                                &copy_func, sizeof(*copy_func)*(copy_func_count+1),
851
869
                                                &param->start_recinfo, sizeof(*param->recinfo)*(field_count*2+4),
852
870
                                                &group_buff, (group && ! using_unique_constraint ?
853
871
                                                              param->group_length : 0),
 
872
                                                &bitmaps, bitmap_buffer_size(field_count)*2,
854
873
                                                NULL))
855
874
  {
856
875
    return NULL;
863
882
  param->items_to_copy= copy_func;
864
883
  /* make table according to fields */
865
884
 
 
885
  table= share->getTable();
 
886
 
866
887
  memset(default_field, 0, sizeof(Field*) * (field_count));
867
888
  memset(from_field, 0, sizeof(Field*)*field_count);
868
889
 
869
890
  mem_root_save= session->mem_root;
870
891
  session->mem_root= table->getMemRoot();
871
892
 
872
 
  table->getMutableShare()->setFields(field_count+1);
873
 
  table->setFields(table->getMutableShare()->getFields(true));
874
 
  reg_field= table->getMutableShare()->getFields(true);
875
 
  table->setAlias(table_alias);
 
893
  share->setFields(field_count+1);
 
894
  table->setFields(share->getFields(true));
 
895
  reg_field= share->getFields(true);
 
896
  table->alias= table_alias;
876
897
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
877
898
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
878
899
  table->map=1;
883
904
  table->covering_keys.reset();
884
905
  table->keys_in_use_for_query.reset();
885
906
 
886
 
  table->getMutableShare()->blob_field.resize(field_count+1);
887
 
  uint32_t *blob_field= &table->getMutableShare()->blob_field[0];
888
 
  table->getMutableShare()->db_low_byte_first=1;                // True for HEAP and MyISAM
889
 
  table->getMutableShare()->table_charset= param->table_charset;
890
 
  table->getMutableShare()->keys_for_keyread.reset();
891
 
  table->getMutableShare()->keys_in_use.reset();
 
907
  table->setShare(share);
 
908
  share->blob_field.resize(field_count+1);
 
909
  uint32_t *blob_field= &share->blob_field[0];
 
910
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
911
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
 
912
  share->table_charset= param->table_charset;
 
913
  share->keys_for_keyread.reset();
 
914
  share->keys_in_use.reset();
892
915
 
893
916
  /* Calculate which type of fields we will store in the temporary table */
894
917
 
965
988
            */
966
989
            (*argp)->maybe_null=1;
967
990
          }
968
 
          new_field->setPosition(fieldnr++);
 
991
          new_field->field_index= fieldnr++;
969
992
        }
970
993
      }
971
994
    }
1012
1035
        group_null_items++;
1013
1036
        new_field->flags|= GROUP_FLAG;
1014
1037
      }
1015
 
      new_field->setPosition(fieldnr++);
 
1038
      new_field->field_index= fieldnr++;
1016
1039
      *(reg_field++)= new_field;
1017
1040
    }
1018
1041
    if (!--hidden_field_count)
1035
1058
  field_count= fieldnr;
1036
1059
  *reg_field= 0;
1037
1060
  *blob_field= 0;                               // End marker
1038
 
  table->getMutableShare()->setFieldSize(field_count);
 
1061
  share->fields= field_count;
1039
1062
 
1040
1063
  /* If result table is small; use a heap */
1041
1064
  /* future: storage engine selection can be made dynamic? */
1044
1067
      (session->lex->current_select->olap == ROLLUP_TYPE) ||
1045
1068
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
1046
1069
  {
1047
 
    table->getMutableShare()->storage_engine= myisam_engine;
1048
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
1070
    share->storage_engine= myisam_engine;
 
1071
    table->cursor= share->db_type()->getCursor(*share);
1049
1072
    if (group &&
1050
1073
        (param->group_parts > table->cursor->getEngine()->max_key_parts() ||
1051
1074
         param->group_length > table->cursor->getEngine()->max_key_length()))
1055
1078
  }
1056
1079
  else
1057
1080
  {
1058
 
    table->getMutableShare()->storage_engine= heap_engine;
1059
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
1081
    share->storage_engine= heap_engine;
 
1082
    table->cursor= share->db_type()->getCursor(*share);
1060
1083
  }
1061
1084
  if (! table->cursor)
1062
1085
    goto err;
1065
1088
  if (! using_unique_constraint)
1066
1089
    reclength+= group_null_items;       // null flag is stored separately
1067
1090
 
1068
 
  table->getMutableShare()->blob_fields= blob_count;
 
1091
  share->blob_fields= blob_count;
1069
1092
  if (blob_count == 0)
1070
1093
  {
1071
1094
    /* We need to ensure that first byte is not 0 for the delete link */
1084
1107
  if (blob_count || ((string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS) && (reclength / string_total_length <= RATIO_TO_PACK_ROWS || (string_total_length / string_count) >= AVG_STRING_LENGTH_TO_PACK_ROWS)))
1085
1108
    use_packed_rows= 1;
1086
1109
 
1087
 
  table->getMutableShare()->setRecordLength(reclength);
 
1110
  share->setRecordLength(reclength);
1088
1111
  {
1089
1112
    uint32_t alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
1090
 
    table->getMutableShare()->rec_buff_length= alloc_length;
 
1113
    share->rec_buff_length= alloc_length;
1091
1114
    if (!(table->record[0]= (unsigned char*) table->alloc_root(alloc_length*2)))
1092
1115
    {
1093
1116
      goto err;
1094
1117
    }
1095
1118
    table->record[1]= table->getInsertRecord()+alloc_length;
1096
 
    table->getMutableShare()->resizeDefaultValues(alloc_length);
 
1119
    share->resizeDefaultValues(alloc_length);
1097
1120
  }
1098
1121
  copy_func[0]= 0;                              // End marker
1099
1122
  param->func_count= copy_func - param->items_to_copy;
1100
1123
 
1101
 
  table->setup_tmp_table_column_bitmaps();
 
1124
  table->setup_tmp_table_column_bitmaps(bitmaps);
1102
1125
 
1103
1126
  recinfo=param->start_recinfo;
1104
1127
  null_flags=(unsigned char*) table->getInsertRecord();
1112
1135
    memset(null_flags, 255, null_pack_length);  // Set null fields
1113
1136
 
1114
1137
    table->null_flags= (unsigned char*) table->getInsertRecord();
1115
 
    table->getMutableShare()->null_fields= null_count+ hidden_null_count;
1116
 
    table->getMutableShare()->null_bytes= null_pack_length;
 
1138
    share->null_fields= null_count+ hidden_null_count;
 
1139
    share->null_bytes= null_pack_length;
1117
1140
  }
1118
1141
  null_count= (blob_count == 0) ? 1 : 0;
1119
1142
  hidden_field_count=param->hidden_field_count;
1204
1227
  }
1205
1228
  else
1206
1229
  {
1207
 
    max_rows= (uint64_t) (((table->getMutableShare()->db_type() == heap_engine) ?
 
1230
    max_rows= (uint64_t) (((share->db_type() == heap_engine) ?
1208
1231
                           min(session->variables.tmp_table_size,
1209
1232
                               session->variables.max_heap_table_size) :
1210
1233
                           session->variables.tmp_table_size) /
1211
 
                          table->getMutableShare()->getRecordLength());
 
1234
                          share->getRecordLength());
1212
1235
  }
1213
1236
 
1214
1237
  set_if_bigger(max_rows, (uint64_t)1); // For dummy start options
1218
1241
  */
1219
1242
  set_if_smaller(max_rows, rows_limit);
1220
1243
 
1221
 
  table->getMutableShare()->setMaxRows(max_rows);
 
1244
  share->setMaxRows(max_rows);
1222
1245
 
1223
1246
  param->end_write_records= rows_limit;
1224
1247
 
1228
1251
  {
1229
1252
    table->group=group;                         /* Table is grouped by key */
1230
1253
    param->group_buff=group_buff;
1231
 
    table->getMutableShare()->keys=1;
1232
 
    table->getMutableShare()->uniques= test(using_unique_constraint);
 
1254
    share->keys=1;
 
1255
    share->uniques= test(using_unique_constraint);
1233
1256
    table->key_info=keyinfo;
1234
1257
    keyinfo->key_part=key_part_info;
1235
1258
    keyinfo->flags=HA_NOSAME;
1238
1261
    keyinfo->rec_per_key= 0;
1239
1262
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1240
1263
    keyinfo->name= (char*) "group_key";
1241
 
    Order *cur_group= group;
 
1264
    order_st *cur_group= group;
1242
1265
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
1243
1266
    {
1244
1267
      Field *field=(*cur_group->item)->get_tmp_table_field();
1300
1323
        indexes on blobs with arbitrary length. Such indexes cannot be
1301
1324
        used for lookups.
1302
1325
      */
1303
 
      table->getMutableShare()->uniques= 1;
 
1326
      share->uniques= 1;
1304
1327
    }
1305
1328
    null_pack_length-=hidden_null_pack_length;
1306
1329
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
1307
 
                         (table->getMutableShare()->uniques ? test(null_pack_length) : 0));
 
1330
                         (share->uniques ? test(null_pack_length) : 0));
1308
1331
    table->distinct= 1;
1309
 
    table->getMutableShare()->keys= 1;
 
1332
    share->keys= 1;
1310
1333
    if (!(key_part_info= (KeyPartInfo*)
1311
1334
         table->alloc_root(keyinfo->key_parts * sizeof(KeyPartInfo))))
1312
1335
      goto err;
1324
1347
      blobs can distinguish NULL from 0. This extra field is not needed
1325
1348
      when we do not use UNIQUE indexes for blobs.
1326
1349
    */
1327
 
    if (null_pack_length && table->getMutableShare()->uniques)
 
1350
    if (null_pack_length && share->uniques)
1328
1351
    {
1329
1352
      key_part_info->null_bit= 0;
1330
1353
      key_part_info->offset=hidden_null_pack_length;
1331
1354
      key_part_info->length=null_pack_length;
1332
 
      table->setVariableWidth();
1333
1355
      key_part_info->field= new Field_varstring(table->getInsertRecord(),
1334
1356
                                                (uint32_t) key_part_info->length,
1335
1357
                                                0,
1336
1358
                                                (unsigned char*) 0,
1337
1359
                                                (uint32_t) 0,
1338
1360
                                                NULL,
 
1361
                                                table->getMutableShare(),
1339
1362
                                                &my_charset_bin);
1340
1363
      if (!key_part_info->field)
1341
1364
        goto err;
1379
1402
 
1380
1403
  if (session->is_fatal_error)                          // If end of memory
1381
1404
    goto err;
1382
 
  table->getMutableShare()->db_record_offset= 1;
1383
 
  if (table->getShare()->db_type() == myisam_engine)
 
1405
  share->db_record_offset= 1;
 
1406
  if (share->db_type() == myisam_engine)
1384
1407
  {
1385
1408
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
1386
1409
                                       &param->recinfo, select_options))
1403
1426
 
1404
1427
/****************************************************************************/
1405
1428
 
1406
 
void Table::column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
1407
 
                               boost::dynamic_bitset<>& write_set_arg)
1408
 
{
1409
 
  read_set= &read_set_arg;
1410
 
  write_set= &write_set_arg;
1411
 
}
1412
 
 
1413
 
 
1414
 
const boost::dynamic_bitset<> Table::use_all_columns(boost::dynamic_bitset<>& in_map)
1415
 
{
1416
 
  const boost::dynamic_bitset<> old= in_map;
1417
 
  in_map= getShare()->all_set;
 
1429
/**
 
1430
  Create a reduced Table object with properly set up Field list from a
 
1431
  list of field definitions.
 
1432
 
 
1433
    The created table doesn't have a table Cursor associated with
 
1434
    it, has no keys, no group/distinct, no copy_funcs array.
 
1435
    The sole purpose of this Table object is to use the power of Field
 
1436
    class to read/write data to/from table->getInsertRecord(). Then one can store
 
1437
    the record in any container (RB tree, hash, etc).
 
1438
    The table is created in Session mem_root, so are the table's fields.
 
1439
    Consequently, if you don't BLOB fields, you don't need to free it.
 
1440
 
 
1441
  @param session         connection handle
 
1442
  @param field_list  list of column definitions
 
1443
 
 
1444
  @return
 
1445
    0 if out of memory, Table object in case of success
 
1446
*/
 
1447
 
 
1448
Table *Session::create_virtual_tmp_table(List<CreateField> &field_list)
 
1449
{
 
1450
  uint32_t field_count= field_list.elements;
 
1451
  uint32_t blob_count= 0;
 
1452
  Field **field;
 
1453
  CreateField *cdef;                           /* column definition */
 
1454
  uint32_t record_length= 0;
 
1455
  uint32_t null_count= 0;                 /* number of columns which may be null */
 
1456
  uint32_t null_pack_length;              /* NULL representation array length */
 
1457
  unsigned char *bitmaps;
 
1458
  Table *table;
 
1459
 
 
1460
  TableShareInstance *share= getTemporaryShare(message::Table::INTERNAL); // This will not go into the tableshare cache, so no key is used.
 
1461
 
 
1462
  if (! share->getMemRoot()->multi_alloc_root(0,
 
1463
                                              &bitmaps, bitmap_buffer_size(field_count)*2,
 
1464
                                              NULL))
 
1465
  {
 
1466
    return NULL;
 
1467
  }
 
1468
 
 
1469
  table= share->getTable();
 
1470
  share->setFields(field_count + 1);
 
1471
  table->setFields(share->getFields(true));
 
1472
  field= share->getFields(true);
 
1473
  share->blob_field.resize(field_count+1);
 
1474
  share->fields= field_count;
 
1475
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
1476
  table->setup_tmp_table_column_bitmaps(bitmaps);
 
1477
 
 
1478
  table->in_use= this;           /* field->reset() may access table->in_use */
 
1479
 
 
1480
  /* Create all fields and calculate the total length of record */
 
1481
  List_iterator_fast<CreateField> it(field_list);
 
1482
  while ((cdef= it++))
 
1483
  {
 
1484
    *field= share->make_field(NULL,
 
1485
                              cdef->length,
 
1486
                              (cdef->flags & NOT_NULL_FLAG) ? false : true,
 
1487
                              (unsigned char *) ((cdef->flags & NOT_NULL_FLAG) ? 0 : ""),
 
1488
                              (cdef->flags & NOT_NULL_FLAG) ? 0 : 1,
 
1489
                              cdef->decimals,
 
1490
                              cdef->sql_type,
 
1491
                              cdef->charset,
 
1492
                              cdef->unireg_check,
 
1493
                              cdef->interval,
 
1494
                              cdef->field_name);
 
1495
    if (!*field)
 
1496
      goto error;
 
1497
    (*field)->init(table);
 
1498
    record_length+= (*field)->pack_length();
 
1499
    if (! ((*field)->flags & NOT_NULL_FLAG))
 
1500
      null_count++;
 
1501
 
 
1502
    if ((*field)->flags & BLOB_FLAG)
 
1503
      share->blob_field[blob_count++]= (uint32_t) (field - table->getFields());
 
1504
 
 
1505
    field++;
 
1506
  }
 
1507
  *field= NULL;                             /* mark the end of the list */
 
1508
  share->blob_field[blob_count]= 0;            /* mark the end of the list */
 
1509
  share->blob_fields= blob_count;
 
1510
 
 
1511
  null_pack_length= (null_count + 7)/8;
 
1512
  share->setRecordLength(record_length + null_pack_length);
 
1513
  share->rec_buff_length= ALIGN_SIZE(share->getRecordLength() + 1);
 
1514
  table->record[0]= (unsigned char*)alloc(share->rec_buff_length);
 
1515
  if (not table->getInsertRecord())
 
1516
    goto error;
 
1517
 
 
1518
  if (null_pack_length)
 
1519
  {
 
1520
    table->null_flags= (unsigned char*) table->getInsertRecord();
 
1521
    share->null_fields= null_count;
 
1522
    share->null_bytes= null_pack_length;
 
1523
  }
 
1524
  {
 
1525
    /* Set up field pointers */
 
1526
    unsigned char *null_pos= table->getInsertRecord();
 
1527
    unsigned char *field_pos= null_pos + share->null_bytes;
 
1528
    uint32_t null_bit= 1;
 
1529
 
 
1530
    for (field= table->getFields(); *field; ++field)
 
1531
    {
 
1532
      Field *cur_field= *field;
 
1533
      if ((cur_field->flags & NOT_NULL_FLAG))
 
1534
        cur_field->move_field(field_pos);
 
1535
      else
 
1536
      {
 
1537
        cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
 
1538
        null_bit<<= 1;
 
1539
        if (null_bit == (1 << 8))
 
1540
        {
 
1541
          ++null_pos;
 
1542
          null_bit= 1;
 
1543
        }
 
1544
      }
 
1545
      cur_field->reset();
 
1546
 
 
1547
      field_pos+= cur_field->pack_length();
 
1548
    }
 
1549
  }
 
1550
 
 
1551
  return table;
 
1552
 
 
1553
error:
 
1554
  for (field= table->getFields(); *field; ++field)
 
1555
  {
 
1556
    delete *field;                         /* just invokes field destructor */
 
1557
  }
 
1558
  return 0;
 
1559
}
 
1560
 
 
1561
bool Table::open_tmp_table()
 
1562
{
 
1563
  int error;
 
1564
  
 
1565
  TableIdentifier identifier(s->getSchemaName(), s->getTableName(), s->getPath());
 
1566
  if ((error=cursor->ha_open(identifier,
 
1567
                             this,
 
1568
                             O_RDWR,
 
1569
                             HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
 
1570
  {
 
1571
    print_error(error, MYF(0));
 
1572
    db_stat= 0;
 
1573
    return true;
 
1574
  }
 
1575
  (void) cursor->extra(HA_EXTRA_QUICK);         /* Faster */
 
1576
  return false;
 
1577
}
 
1578
 
 
1579
 
 
1580
/*
 
1581
  Create MyISAM temporary table
 
1582
 
 
1583
  SYNOPSIS
 
1584
    create_myisam_tmp_table()
 
1585
      keyinfo         Description of the index (there is always one index)
 
1586
      start_recinfo   MyISAM's column descriptions
 
1587
      recinfo INOUT   End of MyISAM's column descriptions
 
1588
      options         Option bits
 
1589
 
 
1590
  DESCRIPTION
 
1591
    Create a MyISAM temporary table according to passed description. The is
 
1592
    assumed to have one unique index or constraint.
 
1593
 
 
1594
    The passed array or MI_COLUMNDEF structures must have this form:
 
1595
 
 
1596
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
 
1597
         when there are many nullable columns)
 
1598
      2. Table columns
 
1599
      3. One free MI_COLUMNDEF element (*recinfo points here)
 
1600
 
 
1601
    This function may use the free element to create hash column for unique
 
1602
    constraint.
 
1603
 
 
1604
   RETURN
 
1605
     false - OK
 
1606
     true  - Error
 
1607
*/
 
1608
 
 
1609
bool Table::create_myisam_tmp_table(KeyInfo *keyinfo,
 
1610
                                    MI_COLUMNDEF *start_recinfo,
 
1611
                                    MI_COLUMNDEF **recinfo,
 
1612
                                    uint64_t options)
 
1613
{
 
1614
  int error;
 
1615
  MI_KEYDEF keydef;
 
1616
  MI_UNIQUEDEF uniquedef;
 
1617
  TableShare *share= s;
 
1618
 
 
1619
  if (share->sizeKeys())
 
1620
  {                                             // Get keys for ni_create
 
1621
    bool using_unique_constraint= false;
 
1622
    HA_KEYSEG *seg= (HA_KEYSEG*) this->mem_root.alloc_root(sizeof(*seg) * keyinfo->key_parts);
 
1623
    if (not seg)
 
1624
      return true;
 
1625
 
 
1626
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
 
1627
    if (keyinfo->key_length >= cursor->getEngine()->max_key_length() ||
 
1628
        keyinfo->key_parts > cursor->getEngine()->max_key_parts() ||
 
1629
        share->uniques)
 
1630
    {
 
1631
      /* Can't create a key; Make a unique constraint instead of a key */
 
1632
      share->keys=    0;
 
1633
      share->uniques= 1;
 
1634
      using_unique_constraint= true;
 
1635
      memset(&uniquedef, 0, sizeof(uniquedef));
 
1636
      uniquedef.keysegs=keyinfo->key_parts;
 
1637
      uniquedef.seg=seg;
 
1638
      uniquedef.null_are_equal=1;
 
1639
 
 
1640
      /* Create extra column for hash value */
 
1641
      memset(*recinfo, 0, sizeof(**recinfo));
 
1642
      (*recinfo)->type= FIELD_CHECK;
 
1643
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
 
1644
      (*recinfo)++;
 
1645
      share->setRecordLength(share->getRecordLength() + MI_UNIQUE_HASH_LENGTH);
 
1646
    }
 
1647
    else
 
1648
    {
 
1649
      /* Create an unique key */
 
1650
      memset(&keydef, 0, sizeof(keydef));
 
1651
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
 
1652
      keydef.keysegs=  keyinfo->key_parts;
 
1653
      keydef.seg= seg;
 
1654
    }
 
1655
    for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
 
1656
    {
 
1657
      Field *key_field=keyinfo->key_part[i].field;
 
1658
      seg->flag=     0;
 
1659
      seg->language= key_field->charset()->number;
 
1660
      seg->length=   keyinfo->key_part[i].length;
 
1661
      seg->start=    keyinfo->key_part[i].offset;
 
1662
      if (key_field->flags & BLOB_FLAG)
 
1663
      {
 
1664
        seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
 
1665
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
 
1666
        seg->bit_start= (uint8_t)(key_field->pack_length()
 
1667
                                  - share->blob_ptr_size);
 
1668
        seg->flag= HA_BLOB_PART;
 
1669
        seg->length= 0;                 // Whole blob in unique constraint
 
1670
      }
 
1671
      else
 
1672
      {
 
1673
        seg->type= keyinfo->key_part[i].type;
 
1674
      }
 
1675
      if (!(key_field->flags & NOT_NULL_FLAG))
 
1676
      {
 
1677
        seg->null_bit= key_field->null_bit;
 
1678
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) getInsertRecord());
 
1679
        /*
 
1680
          We are using a GROUP BY on something that contains NULL
 
1681
          In this case we have to tell MyISAM that two NULL should
 
1682
          on INSERT be regarded at the same value
 
1683
        */
 
1684
        if (! using_unique_constraint)
 
1685
          keydef.flag|= HA_NULL_ARE_EQUAL;
 
1686
      }
 
1687
    }
 
1688
  }
 
1689
  MI_CREATE_INFO create_info;
 
1690
 
 
1691
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
1692
      OPTION_BIG_TABLES)
 
1693
    create_info.data_file_length= ~(uint64_t) 0;
 
1694
 
 
1695
  if ((error= mi_create(share->getTableName(), share->sizeKeys(), &keydef,
 
1696
                        (uint32_t) (*recinfo-start_recinfo),
 
1697
                        start_recinfo,
 
1698
                        share->uniques, &uniquedef,
 
1699
                        &create_info,
 
1700
                        HA_CREATE_TMP_TABLE)))
 
1701
  {
 
1702
    print_error(error, MYF(0));
 
1703
    db_stat= 0;
 
1704
 
 
1705
    return true;
 
1706
  }
 
1707
  in_use->status_var.created_tmp_disk_tables++;
 
1708
  share->db_record_offset= 1;
 
1709
  return false;
 
1710
}
 
1711
 
 
1712
 
 
1713
void Table::free_tmp_table(Session *session)
 
1714
{
 
1715
  memory::Root own_root= mem_root;
 
1716
  const char *save_proc_info;
 
1717
 
 
1718
  save_proc_info= session->get_proc_info();
 
1719
  session->set_proc_info("removing tmp table");
 
1720
 
 
1721
  // Release latches since this can take a long time
 
1722
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
1723
 
 
1724
  if (cursor)
 
1725
  {
 
1726
    if (db_stat)
 
1727
    {
 
1728
      cursor->closeMarkForDelete(s->getTableName());
 
1729
    }
 
1730
 
 
1731
    TableIdentifier identifier(s->getSchemaName(), s->getTableName(), s->getTableName());
 
1732
    s->db_type()->doDropTable(*session, identifier);
 
1733
 
 
1734
    delete cursor;
 
1735
  }
 
1736
 
 
1737
  /* free blobs */
 
1738
  for (Field **ptr= field ; *ptr ; ptr++)
 
1739
  {
 
1740
    (*ptr)->free();
 
1741
  }
 
1742
  free_io_cache();
 
1743
 
 
1744
  own_root.free_root(MYF(0)); /* the table is allocated in its own root */
 
1745
  session->set_proc_info(save_proc_info);
 
1746
}
 
1747
 
 
1748
my_bitmap_map *Table::use_all_columns(MyBitmap *bitmap)
 
1749
{
 
1750
  my_bitmap_map *old= bitmap->getBitmap();
 
1751
  bitmap->setBitmap(s->all_set.getBitmap());
1418
1752
  return old;
1419
1753
}
1420
1754
 
1421
 
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
 
1755
void Table::restore_column_map(my_bitmap_map *old)
1422
1756
{
1423
 
  for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
1424
 
  {
1425
 
    if (old.test(i))
1426
 
    {
1427
 
      read_set->set(i);
1428
 
    }
1429
 
    else
1430
 
    {
1431
 
      read_set->reset(i);
1432
 
    }
1433
 
  }
 
1757
  read_set->setBitmap(old);
1434
1758
}
1435
1759
 
1436
1760
uint32_t Table::find_shortest_key(const key_map *usable_keys)
1439
1763
  uint32_t best= MAX_KEY;
1440
1764
  if (usable_keys->any())
1441
1765
  {
1442
 
    for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
 
1766
    for (uint32_t nr= 0; nr < s->sizeKeys() ; nr++)
1443
1767
    {
1444
1768
      if (usable_keys->test(nr))
1445
1769
      {
1466
1790
{
1467
1791
  for (; *ptr ; ptr++)
1468
1792
  {
1469
 
    if ((*ptr)->cmp_offset(getShare()->rec_buff_length))
 
1793
    if ((*ptr)->cmp_offset(s->rec_buff_length))
1470
1794
      return true;
1471
1795
  }
1472
1796
  return false;
1473
1797
}
1474
1798
 
1475
 
/**
1476
 
   True if the table's input and output record buffers are comparable using
1477
 
   compare_records(TABLE*).
1478
 
 */
1479
 
bool Table::records_are_comparable()
1480
 
{
1481
 
  return ((getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) == 0) ||
1482
 
          write_set->is_subset_of(*read_set));
1483
 
}
1484
 
 
1485
 
/**
1486
 
   Compares the input and outbut record buffers of the table to see if a row
1487
 
   has changed. The algorithm iterates over updated columns and if they are
1488
 
   nullable compares NULL bits in the buffer before comparing actual
1489
 
   data. Special care must be taken to compare only the relevant NULL bits and
1490
 
   mask out all others as they may be undefined. The storage engine will not
1491
 
   and should not touch them.
1492
 
 
1493
 
   @param table The table to evaluate.
1494
 
 
1495
 
   @return true if row has changed.
1496
 
   @return false otherwise.
1497
 
*/
1498
 
bool Table::compare_records()
1499
 
{
1500
 
  if (getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) != 0)
1501
 
  {
1502
 
    /*
1503
 
      Storage engine may not have read all columns of the record.  Fields
1504
 
      (including NULL bits) not in the write_set may not have been read and
1505
 
      can therefore not be compared.
1506
 
    */
1507
 
    for (Field **ptr= this->field ; *ptr != NULL; ptr++)
1508
 
    {
1509
 
      Field *f= *ptr;
1510
 
      if (write_set->test(f->position()))
1511
 
      {
1512
 
        if (f->real_maybe_null())
1513
 
        {
1514
 
          unsigned char null_byte_index= f->null_ptr - record[0];
1515
 
 
1516
 
          if (((record[0][null_byte_index]) & f->null_bit) !=
1517
 
              ((record[1][null_byte_index]) & f->null_bit))
1518
 
            return true;
1519
 
        }
1520
 
        if (f->cmp_binary_offset(getShare()->rec_buff_length))
1521
 
          return true;
1522
 
      }
1523
 
    }
1524
 
    return false;
1525
 
  }
1526
 
 
1527
 
  /*
1528
 
    The storage engine has read all columns, so it's safe to compare all bits
1529
 
    including those not in the write_set. This is cheaper than the
1530
 
    field-by-field comparison done above.
1531
 
  */
1532
 
  if (not getShare()->blob_fields + getShare()->hasVariableWidth())
1533
 
    // Fixed-size record: do bitwise comparison of the records
1534
 
    return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) getShare()->getRecordLength());
1535
 
 
 
1799
/* Return false if row hasn't changed */
 
1800
 
 
1801
bool Table::compare_record()
 
1802
{
 
1803
  if (s->blob_fields + s->varchar_fields == 0)
 
1804
    return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) s->getRecordLength());
 
1805
  
1536
1806
  /* Compare null bits */
1537
 
  if (memcmp(null_flags, null_flags + getShare()->rec_buff_length, getShare()->null_bytes))
 
1807
  if (memcmp(null_flags, null_flags + s->rec_buff_length, s->null_bytes))
1538
1808
    return true; /* Diff in NULL value */
1539
1809
 
1540
1810
  /* Compare updated fields */
1541
1811
  for (Field **ptr= field ; *ptr ; ptr++)
1542
1812
  {
1543
 
    if (isWriteSet((*ptr)->position()) &&
1544
 
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
 
1813
    if (isWriteSet((*ptr)->field_index) &&
 
1814
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
1545
1815
      return true;
1546
1816
  }
1547
1817
  return false;
1553
1823
 */
1554
1824
void Table::storeRecord()
1555
1825
{
1556
 
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1826
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) s->getRecordLength());
1557
1827
}
1558
1828
 
1559
1829
/*
1562
1832
 */
1563
1833
void Table::storeRecordAsInsert()
1564
1834
{
1565
 
  assert(insert_values.size() >= getShare()->getRecordLength());
1566
 
  memcpy(&insert_values[0], getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1835
  assert(insert_values.size() >= s->getRecordLength());
 
1836
  memcpy(&insert_values[0], getInsertRecord(), (size_t) s->getRecordLength());
1567
1837
}
1568
1838
 
1569
1839
/*
1572
1842
 */
1573
1843
void Table::storeRecordAsDefault()
1574
1844
{
1575
 
  memcpy(getMutableShare()->getDefaultValues(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1845
  memcpy(s->getDefaultValues(), getInsertRecord(), (size_t) s->getRecordLength());
1576
1846
}
1577
1847
 
1578
1848
/*
1581
1851
 */
1582
1852
void Table::restoreRecord()
1583
1853
{
1584
 
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) getShare()->getRecordLength());
 
1854
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) s->getRecordLength());
1585
1855
}
1586
1856
 
1587
1857
/*
1590
1860
 */
1591
1861
void Table::restoreRecordAsDefault()
1592
1862
{
1593
 
  memcpy(getInsertRecord(), getMutableShare()->getDefaultValues(), (size_t) getShare()->getRecordLength());
 
1863
  memcpy(getInsertRecord(), s->getDefaultValues(), (size_t) s->getRecordLength());
1594
1864
}
1595
1865
 
1596
1866
/*
1600
1870
void Table::emptyRecord()
1601
1871
{
1602
1872
  restoreRecordAsDefault();
1603
 
  memset(null_flags, 255, getShare()->null_bytes);
 
1873
  memset(null_flags, 255, s->null_bytes);
1604
1874
}
1605
1875
 
1606
1876
Table::Table() : 
 
1877
  s(NULL),
1607
1878
  field(NULL),
1608
1879
  cursor(NULL),
1609
1880
  next(NULL),
1612
1883
  write_set(NULL),
1613
1884
  tablenr(0),
1614
1885
  db_stat(0),
1615
 
  def_read_set(),
1616
 
  def_write_set(),
1617
 
  tmp_set(),
1618
1886
  in_use(NULL),
1619
1887
  key_info(NULL),
1620
1888
  next_number_field(NULL),
1622
1890
  timestamp_field(NULL),
1623
1891
  pos_in_table_list(NULL),
1624
1892
  group(NULL),
 
1893
  alias(NULL),
1625
1894
  null_flags(NULL),
1626
1895
  lock_position(0),
1627
1896
  lock_data_start(0),
1648
1917
  quick_condition_rows(0),
1649
1918
  timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
1650
1919
  map(0),
1651
 
  quick_rows(),
1652
 
  const_key_parts(),
1653
 
  quick_key_parts(),
1654
 
  quick_n_ranges()
 
1920
  is_placeholder_created(0)
1655
1921
{
 
1922
  memset(&def_read_set, 0, sizeof(MyBitmap)); /**< Default read set of columns */
 
1923
  memset(&def_write_set, 0, sizeof(MyBitmap)); /**< Default write set of columns */
 
1924
  memset(&tmp_set, 0, sizeof(MyBitmap)); /* Not sure about this... */
 
1925
 
1656
1926
  record[0]= (unsigned char *) 0;
1657
1927
  record[1]= (unsigned char *) 0;
 
1928
 
 
1929
  reginfo.reset();
 
1930
  covering_keys.reset();
 
1931
  quick_keys.reset();
 
1932
  merge_keys.reset();
 
1933
 
 
1934
  keys_in_use_for_query.reset();
 
1935
  keys_in_use_for_group_by.reset();
 
1936
  keys_in_use_for_order_by.reset();
 
1937
 
 
1938
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
 
1939
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
 
1940
 
 
1941
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
 
1942
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
1658
1943
}
1659
1944
 
1660
1945
/*****************************************************************************
1676
1961
    print them to the .err log
1677
1962
  */
1678
1963
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
1679
 
    errmsg_printf(error::ERROR, _("Got error %d when reading table '%s'"),
1680
 
                  error, getShare()->getPath());
 
1964
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
 
1965
                  error, s->getPath());
1681
1966
  print_error(error, MYF(0));
1682
1967
 
1683
1968
  return 1;
1700
1985
  tablenr= table_number;
1701
1986
  map= (table_map) 1 << table_number;
1702
1987
  force_index= table_list->force_index;
1703
 
  covering_keys= getShare()->keys_for_keyread;
 
1988
  covering_keys= s->keys_for_keyread;
1704
1989
  merge_keys.reset();
1705
1990
}
1706
1991
 
1720
2005
  return false;
1721
2006
}
1722
2007
 
1723
 
 
1724
 
void Table::filesort_free_buffers(bool full)
1725
 
{
1726
 
  if (sort.record_pointers)
1727
 
  {
1728
 
    free((unsigned char*) sort.record_pointers);
1729
 
    sort.record_pointers=0;
1730
 
  }
1731
 
  if (full)
1732
 
  {
1733
 
    if (sort.sort_keys )
1734
 
    {
1735
 
      if ((unsigned char*) sort.sort_keys)
1736
 
        free((unsigned char*) sort.sort_keys);
1737
 
      sort.sort_keys= 0;
1738
 
    }
1739
 
    if (sort.buffpek)
1740
 
    {
1741
 
      if ((unsigned char*) sort.buffpek)
1742
 
        free((unsigned char*) sort.buffpek);
1743
 
      sort.buffpek= 0;
1744
 
      sort.buffpek_len= 0;
1745
 
    }
1746
 
  }
1747
 
 
1748
 
  if (sort.addon_buf)
1749
 
  {
1750
 
    free((char *) sort.addon_buf);
1751
 
    free((char *) sort.addon_field);
1752
 
    sort.addon_buf=0;
1753
 
    sort.addon_field=0;
1754
 
  }
1755
 
}
1756
 
 
1757
 
/*
1758
 
  Is this instance of the table should be reopen or represents a name-lock?
1759
 
*/
1760
 
bool Table::needs_reopen_or_name_lock() const
1761
 
1762
 
  return getShare()->getVersion() != refresh_version;
1763
 
}
1764
 
 
1765
 
uint32_t Table::index_flags(uint32_t idx) const
1766
 
{
1767
 
  return getShare()->getEngine()->index_flags(getShare()->getKeyInfo(idx).algorithm);
1768
 
}
1769
 
 
1770
 
void Table::print_error(int error, myf errflag) const
1771
 
{
1772
 
  getShare()->getEngine()->print_error(error, errflag, *this);
1773
 
}
1774
 
 
1775
2008
} /* namespace drizzled */