~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Prafulla Tekawade
  • Date: 2010-07-18 03:36:32 UTC
  • mto: (1662.1.4 rollup)
  • mto: This revision was merged to the branch mainline in revision 1664.
  • Revision ID: prafulla_t@users.sourceforge.net-20100718033632-p7q6qtgliqbhe38p
Fix for Bug 592444

There were two problems:
o. In greedy_search optimizer method, best_extension_by_limited search
   maintains join embedding(nestedness) of tables added so far, so that 
   correct(valid)  join order is selected
   These are requirements from nested outer join executioner.
   The problem was, embedding_map was not correctly updated when a table 
   is added to optimal plan outside best_extension_by_limited search, 
   by greedy_search method. We need to update join->cur_embedding_map
   correctly here so that execution plan for other tables get
   generated.
   Invoked checked_interleaving_with_nj from greedy_search on the
   best_table selected. Fixed its prototype to take only one JoinTab
   This is same as mysql 5.1 source tree.
o. The other problem was, join->cur_embedding_map was not restored correctly
   when a table is added to the optimal plan to reflect the current embedding 
   map. 
   Taken good documented method restore_prev_nj_state which restores 
   cur_embedding_map from mysql 5.1 source tree and modified it for drizzled 
   code.

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 */
54
54
#include <drizzled/item/null.h>
55
55
#include <drizzled/temporal.h>
56
56
 
57
 
#include "drizzled/table/instance.h"
 
57
#include "drizzled/table_share_instance.h"
58
58
 
59
59
#include "drizzled/table_proto.h"
60
60
 
81
81
 
82
82
  if (db_stat)
83
83
    error= cursor->close();
84
 
  _alias.clear();
 
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
      assert(s->newed);
 
106
      delete s;
 
107
    }
 
108
 
 
109
    s= NULL;
99
110
  }
 
111
  mem_root.free_root(MYF(0));
100
112
 
101
113
  return error;
102
114
}
103
115
 
104
 
Table::~Table()
105
 
{
106
 
  mem_root.free_root(MYF(0));
107
 
}
108
 
 
109
116
 
110
117
void Table::resetTable(Session *session,
111
118
                       TableShare *share,
112
119
                       uint32_t db_stat_arg)
113
120
{
114
 
  setShare(share);
 
121
  s= share;
115
122
  field= NULL;
116
123
 
117
124
  cursor= NULL;
128
135
  record[0]= (unsigned char *) NULL;
129
136
  record[1]= (unsigned char *) NULL;
130
137
 
131
 
  insert_values.clear();
 
138
  insert_values= NULL;
132
139
  key_info= NULL;
133
140
  next_number_field= NULL;
134
141
  found_next_number_field= NULL;
136
143
 
137
144
  pos_in_table_list= NULL;
138
145
  group= NULL;
139
 
  _alias.clear();
 
146
  alias= NULL;
140
147
  null_flags= NULL;
141
148
 
142
149
  lock_position= 0;
190
197
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
191
198
 
192
199
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
200
  memset(&sort, 0, sizeof(filesort_info_st));
193
201
}
194
202
 
195
203
 
247
255
  return (nr);
248
256
} /* set_zone */
249
257
 
 
258
        /* Adjust number to next larger disk buffer */
 
259
 
 
260
ulong next_io_size(register ulong pos)
 
261
{
 
262
  register ulong offset;
 
263
  if ((offset= pos & (IO_SIZE-1)))
 
264
    return pos-offset+IO_SIZE;
 
265
  return pos;
 
266
} /* next_io_size */
 
267
 
250
268
 
251
269
/*
252
270
  Store an SQL quoted string.
274
292
        (mblen= my_ismbchar(default_charset_info, pos, end)))
275
293
    {
276
294
      res->append(pos, mblen);
277
 
      pos+= mblen - 1;
 
295
      pos+= mblen;
278
296
      if (pos >= end)
279
297
        break;
280
298
      continue;
310
328
}
311
329
 
312
330
 
 
331
/*
 
332
  Set up column usage bitmaps for a temporary table
 
333
 
 
334
  IMPLEMENTATION
 
335
    For temporary tables, we need one bitmap with all columns set and
 
336
    a tmp_set bitmap to be used by things like filesort.
 
337
*/
 
338
 
 
339
void Table::setup_tmp_table_column_bitmaps(unsigned char *bitmaps)
 
340
{
 
341
  uint32_t field_count= s->sizeFields();
 
342
 
 
343
  this->def_read_set.init((my_bitmap_map*) bitmaps, field_count);
 
344
  this->tmp_set.init((my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count);
 
345
 
 
346
  /* write_set and all_set are copies of read_set */
 
347
  def_write_set= def_read_set;
 
348
  s->all_set= def_read_set;
 
349
  this->getMutableShare()->all_set.setAll();
 
350
  default_column_bitmaps();
 
351
}
 
352
 
 
353
 
313
354
int rename_file_ext(const char * from,const char * to,const char * ext)
314
355
{
315
356
  string from_s, to_s;
413
454
    bitmap_clear_all(&table->def_read_set);
414
455
    bitmap_clear_all(&table->def_write_set);
415
456
  */
416
 
  def_read_set.reset();
417
 
  def_write_set.reset();
418
 
  column_bitmaps_set(def_read_set, def_write_set);
 
457
  def_read_set.clearAll();
 
458
  def_write_set.clearAll();
 
459
  column_bitmaps_set(&def_read_set, &def_write_set);
419
460
}
420
461
 
421
462
 
432
473
{
433
474
 
434
475
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
435
 
      getShare()->hasPrimaryKey())
 
476
      s->hasPrimaryKey())
436
477
  {
437
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
478
    mark_columns_used_by_index_no_reset(s->getPrimaryKey());
438
479
  }
439
480
  return;
440
481
}
452
493
 
453
494
void Table::mark_columns_used_by_index(uint32_t index)
454
495
{
455
 
  boost::dynamic_bitset<> *bitmap= &tmp_set;
 
496
  MyBitmap *bitmap= &tmp_set;
456
497
 
457
498
  (void) cursor->extra(HA_EXTRA_KEYREAD);
458
 
  bitmap->reset();
459
 
  mark_columns_used_by_index_no_reset(index, *bitmap);
460
 
  column_bitmaps_set(*bitmap, *bitmap);
 
499
  bitmap->clearAll();
 
500
  mark_columns_used_by_index_no_reset(index, bitmap);
 
501
  column_bitmaps_set(bitmap, bitmap);
461
502
  return;
462
503
}
463
504
 
489
530
 
490
531
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
491
532
{
492
 
    mark_columns_used_by_index_no_reset(index, *read_set);
 
533
    mark_columns_used_by_index_no_reset(index, read_set);
493
534
}
494
535
 
495
 
 
496
536
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
497
 
                                                boost::dynamic_bitset<>& bitmap)
 
537
                                                MyBitmap *bitmap)
498
538
{
499
539
  KeyPartInfo *key_part= key_info[index].key_part;
500
 
  KeyPartInfo *key_part_end= (key_part + key_info[index].key_parts);
501
 
  for (; key_part != key_part_end; key_part++)
502
 
  {
503
 
    if (! bitmap.empty())
504
 
      bitmap.set(key_part->fieldnr-1);
505
 
  }
 
540
  KeyPartInfo *key_part_end= (key_part +
 
541
                                key_info[index].key_parts);
 
542
  for (;key_part != key_part_end; key_part++)
 
543
    bitmap->setBit(key_part->fieldnr-1);
506
544
}
507
545
 
508
546
 
521
559
    We must set bit in read set as update_auto_increment() is using the
522
560
    store() to check overflow of auto_increment values
523
561
  */
524
 
  setReadSet(found_next_number_field->position());
525
 
  setWriteSet(found_next_number_field->position());
526
 
  if (getShare()->next_number_keypart)
527
 
    mark_columns_used_by_index_no_reset(getShare()->next_number_index);
 
562
  setReadSet(found_next_number_field->field_index);
 
563
  setWriteSet(found_next_number_field->field_index);
 
564
  if (s->next_number_keypart)
 
565
    mark_columns_used_by_index_no_reset(s->next_number_index);
528
566
}
529
567
 
530
568
 
555
593
    be able to do an delete
556
594
 
557
595
  */
558
 
  if (not getShare()->hasPrimaryKey())
 
596
  if (not s->hasPrimaryKey())
559
597
  {
560
598
    /* fallback to use all columns in the table to identify row */
561
599
    use_all_columns();
562
600
    return;
563
601
  }
564
602
  else
565
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
603
    mark_columns_used_by_index_no_reset(s->getPrimaryKey());
566
604
 
567
605
  /* If we the engine wants all predicates we mark all keys */
568
606
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
571
609
    for (reg_field= field ; *reg_field ; reg_field++)
572
610
    {
573
611
      if ((*reg_field)->flags & PART_KEY_FLAG)
574
 
        setReadSet((*reg_field)->position());
 
612
        setReadSet((*reg_field)->field_index);
575
613
    }
576
614
  }
577
615
}
603
641
    the primary key, the hidden primary key or all columns to be
604
642
    able to do an update
605
643
  */
606
 
  if (not getShare()->hasPrimaryKey())
 
644
  if (not s->hasPrimaryKey())
607
645
  {
608
646
    /* fallback to use all columns in the table to identify row */
609
647
    use_all_columns();
610
648
    return;
611
649
  }
612
650
  else
613
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
651
    mark_columns_used_by_index_no_reset(s->getPrimaryKey());
614
652
 
615
653
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
616
654
  {
620
658
    {
621
659
      /* Merge keys is all keys that had a column refered to in the query */
622
660
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
623
 
        setReadSet((*reg_field)->position());
 
661
        setReadSet((*reg_field)->field_index);
624
662
    }
625
663
  }
626
664
 
652
690
  {
653
691
    Field_blob* const blob= (Field_blob*) field[*ptr];
654
692
    length+= blob->get_length((const unsigned char*)
655
 
                              (data + blob->offset(getInsertRecord()))) +
 
693
                              (data + blob->offset(record[0]))) +
656
694
      HA_KEY_BLOB_LENGTH;
657
695
  }
658
696
  return length;
659
697
}
660
698
 
661
 
void Table::setVariableWidth(void)
662
 
{
663
 
  assert(in_use);
664
 
  if (in_use && in_use->lex->sql_command == SQLCOM_CREATE_TABLE)
665
 
  {
666
 
    getMutableShare()->setVariableWidth();
667
 
    return;
668
 
  }
669
 
 
670
 
  assert(0); // Programming error, you can't set this on a plain old Table.
671
 
}
672
 
 
673
699
/****************************************************************************
674
700
 Functions for creating temporary tables.
675
701
****************************************************************************/
707
733
  */
708
734
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
709
735
      (org_field->flags & BLOB_FLAG))
710
 
  {
711
 
    table->setVariableWidth();
712
736
    new_field= new Field_varstring(convert_blob_length,
713
737
                                   org_field->maybe_null(),
714
 
                                   org_field->field_name,
 
738
                                   org_field->field_name, table->getMutableShare(),
715
739
                                   org_field->charset());
716
 
  }
717
740
  else
718
 
  {
719
741
    new_field= org_field->new_field(session->mem_root, table,
720
 
                                    table == org_field->getTable());
721
 
  }
 
742
                                    table == org_field->table);
722
743
  if (new_field)
723
744
  {
724
745
    new_field->init(table);
771
792
 
772
793
Table *
773
794
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
774
 
                 Order *group, bool distinct, bool save_sum_fields,
 
795
                 order_st *group, bool distinct, bool save_sum_fields,
775
796
                 uint64_t select_options, ha_rows rows_limit,
776
797
                 const char *table_alias)
777
798
{
778
799
  memory::Root *mem_root_save;
 
800
  Table *table;
779
801
  uint  i,field_count,null_count,null_pack_length;
780
802
  uint32_t  copy_func_count= param->func_count;
781
803
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
785
807
  bool  using_unique_constraint= false;
786
808
  bool  use_packed_rows= true;
787
809
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
788
 
  unsigned char *pos, *group_buff;
 
810
  unsigned char *pos, *group_buff, *bitmaps;
789
811
  unsigned char *null_flags;
790
812
  Field **reg_field, **from_field, **default_field;
791
813
  CopyField *copy= 0;
797
819
  bool force_copy_fields= param->force_copy_fields;
798
820
  uint64_t max_rows= 0;
799
821
 
800
 
  session->status_var.created_tmp_tables++;
 
822
  status_var_increment(session->status_var.created_tmp_tables);
801
823
 
802
824
  if (group)
803
825
  {
805
827
    {
806
828
      group= 0;                                 // Can't use group key
807
829
    }
808
 
    else for (Order *tmp=group ; tmp ; tmp=tmp->next)
 
830
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
809
831
    {
810
832
      /*
811
833
        marker == 4 means two things:
838
860
    copy_func_count+= param->sum_func_count;
839
861
  }
840
862
 
841
 
  table::Instance *table;
842
 
  table= session->getInstanceTable(); // This will not go into the tableshare cache, so no key is used.
 
863
  TableShareInstance *share= session->getTemporaryShare(message::Table::INTERNAL); // This will not go into the tableshare cache, so no key is used.
843
864
 
844
 
  if (not table->getMemRoot()->multi_alloc_root(0,
 
865
  if (not share->getMemRoot()->multi_alloc_root(0,
845
866
                                                &default_field, sizeof(Field*) * (field_count),
846
867
                                                &from_field, sizeof(Field*)*field_count,
847
868
                                                &copy_func, sizeof(*copy_func)*(copy_func_count+1),
850
871
                                                &param->start_recinfo, sizeof(*param->recinfo)*(field_count*2+4),
851
872
                                                &group_buff, (group && ! using_unique_constraint ?
852
873
                                                              param->group_length : 0),
 
874
                                                &bitmaps, bitmap_buffer_size(field_count)*2,
853
875
                                                NULL))
854
876
  {
855
877
    return NULL;
862
884
  param->items_to_copy= copy_func;
863
885
  /* make table according to fields */
864
886
 
 
887
  table= share->getTable();
 
888
 
865
889
  memset(default_field, 0, sizeof(Field*) * (field_count));
866
890
  memset(from_field, 0, sizeof(Field*)*field_count);
867
891
 
868
892
  mem_root_save= session->mem_root;
869
893
  session->mem_root= table->getMemRoot();
870
894
 
871
 
  table->getMutableShare()->setFields(field_count+1);
872
 
  table->setFields(table->getMutableShare()->getFields(true));
873
 
  reg_field= table->getMutableShare()->getFields(true);
874
 
  table->setAlias(table_alias);
 
895
  share->setFields(field_count+1);
 
896
  table->setFields(share->getFields(true));
 
897
  reg_field= share->getFields(true);
 
898
  table->alias= table_alias;
875
899
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
876
900
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
877
901
  table->map=1;
882
906
  table->covering_keys.reset();
883
907
  table->keys_in_use_for_query.reset();
884
908
 
885
 
  table->getMutableShare()->blob_field.resize(field_count+1);
886
 
  uint32_t *blob_field= &table->getMutableShare()->blob_field[0];
887
 
  table->getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
888
 
  table->getMutableShare()->db_low_byte_first=1;                // True for HEAP and MyISAM
889
 
  table->getMutableShare()->table_charset= param->table_charset;
890
 
  table->getMutableShare()->keys_for_keyread.reset();
891
 
  table->getMutableShare()->keys_in_use.reset();
 
909
  table->setShare(share);
 
910
  share->blob_field.resize(field_count+1);
 
911
  uint32_t *blob_field= &share->blob_field[0];
 
912
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
913
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
 
914
  share->table_charset= param->table_charset;
 
915
  share->keys_for_keyread.reset();
 
916
  share->keys_in_use.reset();
892
917
 
893
918
  /* Calculate which type of fields we will store in the temporary table */
894
919
 
965
990
            */
966
991
            (*argp)->maybe_null=1;
967
992
          }
968
 
          new_field->setPosition(fieldnr++);
 
993
          new_field->field_index= fieldnr++;
969
994
        }
970
995
      }
971
996
    }
1012
1037
        group_null_items++;
1013
1038
        new_field->flags|= GROUP_FLAG;
1014
1039
      }
1015
 
      new_field->setPosition(fieldnr++);
 
1040
      new_field->field_index= fieldnr++;
1016
1041
      *(reg_field++)= new_field;
1017
1042
    }
1018
1043
    if (!--hidden_field_count)
1035
1060
  field_count= fieldnr;
1036
1061
  *reg_field= 0;
1037
1062
  *blob_field= 0;                               // End marker
1038
 
  table->getMutableShare()->fields= field_count;
 
1063
  share->fields= field_count;
1039
1064
 
1040
1065
  /* If result table is small; use a heap */
1041
1066
  /* future: storage engine selection can be made dynamic? */
1044
1069
      (session->lex->current_select->olap == ROLLUP_TYPE) ||
1045
1070
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
1046
1071
  {
1047
 
    table->getMutableShare()->storage_engine= myisam_engine;
1048
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
1072
    share->storage_engine= myisam_engine;
 
1073
    table->cursor= share->db_type()->getCursor(*share, table->getMemRoot());
1049
1074
    if (group &&
1050
1075
        (param->group_parts > table->cursor->getEngine()->max_key_parts() ||
1051
1076
         param->group_length > table->cursor->getEngine()->max_key_length()))
1055
1080
  }
1056
1081
  else
1057
1082
  {
1058
 
    table->getMutableShare()->storage_engine= heap_engine;
1059
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
1083
    share->storage_engine= heap_engine;
 
1084
    table->cursor= share->db_type()->getCursor(*share, table->getMemRoot());
1060
1085
  }
1061
1086
  if (! table->cursor)
1062
1087
    goto err;
1065
1090
  if (! using_unique_constraint)
1066
1091
    reclength+= group_null_items;       // null flag is stored separately
1067
1092
 
1068
 
  table->getMutableShare()->blob_fields= blob_count;
 
1093
  share->blob_fields= blob_count;
1069
1094
  if (blob_count == 0)
1070
1095
  {
1071
1096
    /* We need to ensure that first byte is not 0 for the delete link */
1084
1109
  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
1110
    use_packed_rows= 1;
1086
1111
 
1087
 
  table->getMutableShare()->setRecordLength(reclength);
 
1112
  share->setRecordLength(reclength);
1088
1113
  {
1089
1114
    uint32_t alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
1090
 
    table->getMutableShare()->rec_buff_length= alloc_length;
1091
 
    if (!(table->record[0]= (unsigned char*) table->alloc_root(alloc_length*2)))
 
1115
    share->rec_buff_length= alloc_length;
 
1116
    if (!(table->record[0]= (unsigned char*)
 
1117
                            table->alloc_root(alloc_length*2)))
1092
1118
    {
1093
1119
      goto err;
1094
1120
    }
1095
 
    table->record[1]= table->getInsertRecord()+alloc_length;
1096
 
    table->getMutableShare()->resizeDefaultValues(alloc_length);
 
1121
    table->record[1]= table->record[0]+alloc_length;
 
1122
    share->resizeDefaultValues(alloc_length);
1097
1123
  }
1098
1124
  copy_func[0]= 0;                              // End marker
1099
1125
  param->func_count= copy_func - param->items_to_copy;
1100
1126
 
1101
 
  table->setup_tmp_table_column_bitmaps();
 
1127
  table->setup_tmp_table_column_bitmaps(bitmaps);
1102
1128
 
1103
1129
  recinfo=param->start_recinfo;
1104
 
  null_flags=(unsigned char*) table->getInsertRecord();
1105
 
  pos=table->getInsertRecord()+ null_pack_length;
 
1130
  null_flags=(unsigned char*) table->record[0];
 
1131
  pos=table->record[0]+ null_pack_length;
1106
1132
  if (null_pack_length)
1107
1133
  {
1108
1134
    memset(recinfo, 0, sizeof(*recinfo));
1111
1137
    recinfo++;
1112
1138
    memset(null_flags, 255, null_pack_length);  // Set null fields
1113
1139
 
1114
 
    table->null_flags= (unsigned char*) table->getInsertRecord();
1115
 
    table->getMutableShare()->null_fields= null_count+ hidden_null_count;
1116
 
    table->getMutableShare()->null_bytes= null_pack_length;
 
1140
    table->null_flags= (unsigned char*) table->record[0];
 
1141
    share->null_fields= null_count+ hidden_null_count;
 
1142
    share->null_bytes= null_pack_length;
1117
1143
  }
1118
1144
  null_count= (blob_count == 0) ? 1 : 0;
1119
1145
  hidden_field_count=param->hidden_field_count;
1164
1190
      ptrdiff_t diff;
1165
1191
      Field *orig_field= default_field[i];
1166
1192
      /* Get the value from default_values */
1167
 
      diff= (ptrdiff_t) (orig_field->getTable()->getDefaultValues() - orig_field->getTable()->getInsertRecord());
 
1193
      diff= (ptrdiff_t) (orig_field->table->getDefaultValues() - orig_field->table->record[0]);
1168
1194
      orig_field->move_field_offset(diff);      // Points now at default_values
1169
1195
      if (orig_field->is_real_null())
1170
1196
        field->set_null();
1173
1199
        field->set_notnull();
1174
1200
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
1175
1201
      }
1176
 
      orig_field->move_field_offset(-diff);     // Back to getInsertRecord()
 
1202
      orig_field->move_field_offset(-diff);     // Back to record[0]
1177
1203
    }
1178
1204
 
1179
1205
    if (from_field[i])
1192
1218
      recinfo->type=FIELD_NORMAL;
1193
1219
    if (!--hidden_field_count)
1194
1220
      null_count=(null_count+7) & ~7;           // move to next byte
 
1221
 
 
1222
    // fix table name in field entry
 
1223
    field->table_name= &table->alias;
1195
1224
  }
1196
1225
 
1197
1226
  param->copy_field_end=copy;
1204
1233
  }
1205
1234
  else
1206
1235
  {
1207
 
    max_rows= (uint64_t) (((table->getMutableShare()->db_type() == heap_engine) ?
 
1236
    max_rows= (uint64_t) (((share->db_type() == heap_engine) ?
1208
1237
                           min(session->variables.tmp_table_size,
1209
1238
                               session->variables.max_heap_table_size) :
1210
1239
                           session->variables.tmp_table_size) /
1211
 
                          table->getMutableShare()->getRecordLength());
 
1240
                          share->getRecordLength());
1212
1241
  }
1213
1242
 
1214
1243
  set_if_bigger(max_rows, (uint64_t)1); // For dummy start options
1218
1247
  */
1219
1248
  set_if_smaller(max_rows, rows_limit);
1220
1249
 
1221
 
  table->getMutableShare()->setMaxRows(max_rows);
 
1250
  share->setMaxRows(max_rows);
1222
1251
 
1223
1252
  param->end_write_records= rows_limit;
1224
1253
 
1228
1257
  {
1229
1258
    table->group=group;                         /* Table is grouped by key */
1230
1259
    param->group_buff=group_buff;
1231
 
    table->getMutableShare()->keys=1;
1232
 
    table->getMutableShare()->uniques= test(using_unique_constraint);
 
1260
    share->keys=1;
 
1261
    share->uniques= test(using_unique_constraint);
1233
1262
    table->key_info=keyinfo;
1234
1263
    keyinfo->key_part=key_part_info;
1235
1264
    keyinfo->flags=HA_NOSAME;
1238
1267
    keyinfo->rec_per_key= 0;
1239
1268
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1240
1269
    keyinfo->name= (char*) "group_key";
1241
 
    Order *cur_group= group;
 
1270
    order_st *cur_group= group;
1242
1271
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
1243
1272
    {
1244
1273
      Field *field=(*cur_group->item)->get_tmp_table_field();
1245
1274
      bool maybe_null=(*cur_group->item)->maybe_null;
1246
1275
      key_part_info->null_bit= 0;
1247
1276
      key_part_info->field=  field;
1248
 
      key_part_info->offset= field->offset(table->getInsertRecord());
 
1277
      key_part_info->offset= field->offset(table->record[0]);
1249
1278
      key_part_info->length= (uint16_t) field->key_length();
1250
1279
      key_part_info->type=   (uint8_t) field->key_type();
1251
1280
      key_part_info->key_type= 
1273
1302
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
1274
1303
          key_part_info->null_bit=field->null_bit;
1275
1304
          key_part_info->null_offset= (uint32_t) (field->null_ptr -
1276
 
                                              (unsigned char*) table->getInsertRecord());
 
1305
                                              (unsigned char*) table->record[0]);
1277
1306
          cur_group->buff++;                        // Pointer to field data
1278
1307
          group_buff++;                         // Skipp null flag
1279
1308
        }
1300
1329
        indexes on blobs with arbitrary length. Such indexes cannot be
1301
1330
        used for lookups.
1302
1331
      */
1303
 
      table->getMutableShare()->uniques= 1;
 
1332
      share->uniques= 1;
1304
1333
    }
1305
1334
    null_pack_length-=hidden_null_pack_length;
1306
1335
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
1307
 
                         (table->getMutableShare()->uniques ? test(null_pack_length) : 0));
 
1336
                         (share->uniques ? test(null_pack_length) : 0));
1308
1337
    table->distinct= 1;
1309
 
    table->getMutableShare()->keys= 1;
 
1338
    share->keys= 1;
1310
1339
    if (!(key_part_info= (KeyPartInfo*)
1311
1340
         table->alloc_root(keyinfo->key_parts * sizeof(KeyPartInfo))))
1312
1341
      goto err;
1324
1353
      blobs can distinguish NULL from 0. This extra field is not needed
1325
1354
      when we do not use UNIQUE indexes for blobs.
1326
1355
    */
1327
 
    if (null_pack_length && table->getMutableShare()->uniques)
 
1356
    if (null_pack_length && share->uniques)
1328
1357
    {
1329
1358
      key_part_info->null_bit= 0;
1330
1359
      key_part_info->offset=hidden_null_pack_length;
1331
1360
      key_part_info->length=null_pack_length;
1332
 
      table->setVariableWidth();
1333
 
      key_part_info->field= new Field_varstring(table->getInsertRecord(),
 
1361
      key_part_info->field= new Field_varstring(table->record[0],
1334
1362
                                                (uint32_t) key_part_info->length,
1335
1363
                                                0,
1336
1364
                                                (unsigned char*) 0,
1337
1365
                                                (uint32_t) 0,
1338
1366
                                                NULL,
 
1367
                                                table->getMutableShare(),
1339
1368
                                                &my_charset_bin);
1340
1369
      if (!key_part_info->field)
1341
1370
        goto err;
1351
1380
    {
1352
1381
      key_part_info->null_bit= 0;
1353
1382
      key_part_info->field=    *reg_field;
1354
 
      key_part_info->offset=   (*reg_field)->offset(table->getInsertRecord());
 
1383
      key_part_info->offset=   (*reg_field)->offset(table->record[0]);
1355
1384
      key_part_info->length=   (uint16_t) (*reg_field)->pack_length();
1356
 
      /* @todo The below method of computing the key format length of the
 
1385
      /* TODO:
 
1386
        The below method of computing the key format length of the
1357
1387
        key part is a copy/paste from optimizer/range.cc, and table.cc.
1358
1388
        This should be factored out, e.g. as a method of Field.
1359
1389
        In addition it is not clear if any of the Field::*_length
1379
1409
 
1380
1410
  if (session->is_fatal_error)                          // If end of memory
1381
1411
    goto err;
1382
 
  table->getMutableShare()->db_record_offset= 1;
1383
 
  if (table->getShare()->db_type() == myisam_engine)
 
1412
  share->db_record_offset= 1;
 
1413
  if (share->db_type() == myisam_engine)
1384
1414
  {
1385
1415
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
1386
1416
                                       &param->recinfo, select_options))
1403
1433
 
1404
1434
/****************************************************************************/
1405
1435
 
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;
 
1436
/**
 
1437
  Create a reduced Table object with properly set up Field list from a
 
1438
  list of field definitions.
 
1439
 
 
1440
    The created table doesn't have a table Cursor associated with
 
1441
    it, has no keys, no group/distinct, no copy_funcs array.
 
1442
    The sole purpose of this Table object is to use the power of Field
 
1443
    class to read/write data to/from table->record[0]. Then one can store
 
1444
    the record in any container (RB tree, hash, etc).
 
1445
    The table is created in Session mem_root, so are the table's fields.
 
1446
    Consequently, if you don't BLOB fields, you don't need to free it.
 
1447
 
 
1448
  @param session         connection handle
 
1449
  @param field_list  list of column definitions
 
1450
 
 
1451
  @return
 
1452
    0 if out of memory, Table object in case of success
 
1453
*/
 
1454
 
 
1455
Table *Session::create_virtual_tmp_table(List<CreateField> &field_list)
 
1456
{
 
1457
  uint32_t field_count= field_list.elements;
 
1458
  uint32_t blob_count= 0;
 
1459
  Field **field;
 
1460
  CreateField *cdef;                           /* column definition */
 
1461
  uint32_t record_length= 0;
 
1462
  uint32_t null_count= 0;                 /* number of columns which may be null */
 
1463
  uint32_t null_pack_length;              /* NULL representation array length */
 
1464
  unsigned char *bitmaps;
 
1465
  Table *table;
 
1466
 
 
1467
  TableShareInstance *share= getTemporaryShare(message::Table::INTERNAL); // This will not go into the tableshare cache, so no key is used.
 
1468
 
 
1469
  if (! share->getMemRoot()->multi_alloc_root(0,
 
1470
                                              &bitmaps, bitmap_buffer_size(field_count)*2,
 
1471
                                              NULL))
 
1472
  {
 
1473
    return NULL;
 
1474
  }
 
1475
 
 
1476
  table= share->getTable();
 
1477
  share->setFields(field_count + 1);
 
1478
  table->setFields(share->getFields(true));
 
1479
  field= share->getFields(true);
 
1480
  share->blob_field.resize(field_count+1);
 
1481
  share->fields= field_count;
 
1482
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
1483
  table->setup_tmp_table_column_bitmaps(bitmaps);
 
1484
 
 
1485
  table->in_use= this;           /* field->reset() may access table->in_use */
 
1486
 
 
1487
  /* Create all fields and calculate the total length of record */
 
1488
  List_iterator_fast<CreateField> it(field_list);
 
1489
  while ((cdef= it++))
 
1490
  {
 
1491
    *field= share->make_field(NULL,
 
1492
                              cdef->length,
 
1493
                              (cdef->flags & NOT_NULL_FLAG) ? false : true,
 
1494
                              (unsigned char *) ((cdef->flags & NOT_NULL_FLAG) ? 0 : ""),
 
1495
                              (cdef->flags & NOT_NULL_FLAG) ? 0 : 1,
 
1496
                              cdef->decimals,
 
1497
                              cdef->sql_type,
 
1498
                              cdef->charset,
 
1499
                              cdef->unireg_check,
 
1500
                              cdef->interval,
 
1501
                              cdef->field_name);
 
1502
    if (!*field)
 
1503
      goto error;
 
1504
    (*field)->init(table);
 
1505
    record_length+= (*field)->pack_length();
 
1506
    if (! ((*field)->flags & NOT_NULL_FLAG))
 
1507
      null_count++;
 
1508
 
 
1509
    if ((*field)->flags & BLOB_FLAG)
 
1510
      share->blob_field[blob_count++]= (uint32_t) (field - table->getFields());
 
1511
 
 
1512
    field++;
 
1513
  }
 
1514
  *field= NULL;                             /* mark the end of the list */
 
1515
  share->blob_field[blob_count]= 0;            /* mark the end of the list */
 
1516
  share->blob_fields= blob_count;
 
1517
 
 
1518
  null_pack_length= (null_count + 7)/8;
 
1519
  share->setRecordLength(record_length + null_pack_length);
 
1520
  share->rec_buff_length= ALIGN_SIZE(share->getRecordLength() + 1);
 
1521
  table->record[0]= (unsigned char*)alloc(share->rec_buff_length);
 
1522
  if (!table->record[0])
 
1523
    goto error;
 
1524
 
 
1525
  if (null_pack_length)
 
1526
  {
 
1527
    table->null_flags= (unsigned char*) table->record[0];
 
1528
    share->null_fields= null_count;
 
1529
    share->null_bytes= null_pack_length;
 
1530
  }
 
1531
  {
 
1532
    /* Set up field pointers */
 
1533
    unsigned char *null_pos= table->record[0];
 
1534
    unsigned char *field_pos= null_pos + share->null_bytes;
 
1535
    uint32_t null_bit= 1;
 
1536
 
 
1537
    for (field= table->getFields(); *field; ++field)
 
1538
    {
 
1539
      Field *cur_field= *field;
 
1540
      if ((cur_field->flags & NOT_NULL_FLAG))
 
1541
        cur_field->move_field(field_pos);
 
1542
      else
 
1543
      {
 
1544
        cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
 
1545
        null_bit<<= 1;
 
1546
        if (null_bit == (1 << 8))
 
1547
        {
 
1548
          ++null_pos;
 
1549
          null_bit= 1;
 
1550
        }
 
1551
      }
 
1552
      cur_field->reset();
 
1553
 
 
1554
      field_pos+= cur_field->pack_length();
 
1555
    }
 
1556
  }
 
1557
 
 
1558
  return table;
 
1559
 
 
1560
error:
 
1561
  for (field= table->getFields(); *field; ++field)
 
1562
  {
 
1563
    delete *field;                         /* just invokes field destructor */
 
1564
  }
 
1565
  return 0;
 
1566
}
 
1567
 
 
1568
bool Table::open_tmp_table()
 
1569
{
 
1570
  int error;
 
1571
  
 
1572
  TableIdentifier identifier(s->getSchemaName(), s->getTableName(), s->getPath());
 
1573
  if ((error=cursor->ha_open(identifier,
 
1574
                             this,
 
1575
                             s->getTableName(),
 
1576
                             O_RDWR,
 
1577
                             HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
 
1578
  {
 
1579
    print_error(error, MYF(0));
 
1580
    db_stat= 0;
 
1581
    return true;
 
1582
  }
 
1583
  (void) cursor->extra(HA_EXTRA_QUICK);         /* Faster */
 
1584
  return false;
 
1585
}
 
1586
 
 
1587
 
 
1588
/*
 
1589
  Create MyISAM temporary table
 
1590
 
 
1591
  SYNOPSIS
 
1592
    create_myisam_tmp_table()
 
1593
      keyinfo         Description of the index (there is always one index)
 
1594
      start_recinfo   MyISAM's column descriptions
 
1595
      recinfo INOUT   End of MyISAM's column descriptions
 
1596
      options         Option bits
 
1597
 
 
1598
  DESCRIPTION
 
1599
    Create a MyISAM temporary table according to passed description. The is
 
1600
    assumed to have one unique index or constraint.
 
1601
 
 
1602
    The passed array or MI_COLUMNDEF structures must have this form:
 
1603
 
 
1604
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
 
1605
         when there are many nullable columns)
 
1606
      2. Table columns
 
1607
      3. One free MI_COLUMNDEF element (*recinfo points here)
 
1608
 
 
1609
    This function may use the free element to create hash column for unique
 
1610
    constraint.
 
1611
 
 
1612
   RETURN
 
1613
     false - OK
 
1614
     true  - Error
 
1615
*/
 
1616
 
 
1617
bool Table::create_myisam_tmp_table(KeyInfo *keyinfo,
 
1618
                                    MI_COLUMNDEF *start_recinfo,
 
1619
                                    MI_COLUMNDEF **recinfo,
 
1620
                                    uint64_t options)
 
1621
{
 
1622
  int error;
 
1623
  MI_KEYDEF keydef;
 
1624
  MI_UNIQUEDEF uniquedef;
 
1625
  TableShare *share= s;
 
1626
 
 
1627
  if (share->sizeKeys())
 
1628
  {                                             // Get keys for ni_create
 
1629
    bool using_unique_constraint= false;
 
1630
    HA_KEYSEG *seg= (HA_KEYSEG*) this->mem_root.alloc_root(sizeof(*seg) * keyinfo->key_parts);
 
1631
    if (!seg)
 
1632
      goto err;
 
1633
 
 
1634
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
 
1635
    if (keyinfo->key_length >= cursor->getEngine()->max_key_length() ||
 
1636
        keyinfo->key_parts > cursor->getEngine()->max_key_parts() ||
 
1637
        share->uniques)
 
1638
    {
 
1639
      /* Can't create a key; Make a unique constraint instead of a key */
 
1640
      share->keys=    0;
 
1641
      share->uniques= 1;
 
1642
      using_unique_constraint= true;
 
1643
      memset(&uniquedef, 0, sizeof(uniquedef));
 
1644
      uniquedef.keysegs=keyinfo->key_parts;
 
1645
      uniquedef.seg=seg;
 
1646
      uniquedef.null_are_equal=1;
 
1647
 
 
1648
      /* Create extra column for hash value */
 
1649
      memset(*recinfo, 0, sizeof(**recinfo));
 
1650
      (*recinfo)->type= FIELD_CHECK;
 
1651
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
 
1652
      (*recinfo)++;
 
1653
      share->setRecordLength(share->getRecordLength() + MI_UNIQUE_HASH_LENGTH);
 
1654
    }
 
1655
    else
 
1656
    {
 
1657
      /* Create an unique key */
 
1658
      memset(&keydef, 0, sizeof(keydef));
 
1659
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
 
1660
      keydef.keysegs=  keyinfo->key_parts;
 
1661
      keydef.seg= seg;
 
1662
    }
 
1663
    for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
 
1664
    {
 
1665
      Field *key_field=keyinfo->key_part[i].field;
 
1666
      seg->flag=     0;
 
1667
      seg->language= key_field->charset()->number;
 
1668
      seg->length=   keyinfo->key_part[i].length;
 
1669
      seg->start=    keyinfo->key_part[i].offset;
 
1670
      if (key_field->flags & BLOB_FLAG)
 
1671
      {
 
1672
        seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
 
1673
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
 
1674
        seg->bit_start= (uint8_t)(key_field->pack_length()
 
1675
                                  - share->blob_ptr_size);
 
1676
        seg->flag= HA_BLOB_PART;
 
1677
        seg->length= 0;                 // Whole blob in unique constraint
 
1678
      }
 
1679
      else
 
1680
      {
 
1681
        seg->type= keyinfo->key_part[i].type;
 
1682
      }
 
1683
      if (!(key_field->flags & NOT_NULL_FLAG))
 
1684
      {
 
1685
        seg->null_bit= key_field->null_bit;
 
1686
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
 
1687
        /*
 
1688
          We are using a GROUP BY on something that contains NULL
 
1689
          In this case we have to tell MyISAM that two NULL should
 
1690
          on INSERT be regarded at the same value
 
1691
        */
 
1692
        if (! using_unique_constraint)
 
1693
          keydef.flag|= HA_NULL_ARE_EQUAL;
 
1694
      }
 
1695
    }
 
1696
  }
 
1697
  MI_CREATE_INFO create_info;
 
1698
  memset(&create_info, 0, sizeof(create_info));
 
1699
 
 
1700
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
1701
      OPTION_BIG_TABLES)
 
1702
    create_info.data_file_length= ~(uint64_t) 0;
 
1703
 
 
1704
  if ((error=mi_create(share->getTableName(), share->sizeKeys(), &keydef,
 
1705
                       (uint32_t) (*recinfo-start_recinfo),
 
1706
                       start_recinfo,
 
1707
                       share->uniques, &uniquedef,
 
1708
                       &create_info,
 
1709
                       HA_CREATE_TMP_TABLE)))
 
1710
  {
 
1711
    print_error(error, MYF(0));
 
1712
    db_stat= 0;
 
1713
    goto err;
 
1714
  }
 
1715
  status_var_increment(in_use->status_var.created_tmp_disk_tables);
 
1716
  share->db_record_offset= 1;
 
1717
  return false;
 
1718
 err:
 
1719
  return true;
 
1720
}
 
1721
 
 
1722
 
 
1723
void Table::free_tmp_table(Session *session)
 
1724
{
 
1725
  memory::Root own_root= mem_root;
 
1726
  const char *save_proc_info;
 
1727
 
 
1728
  save_proc_info= session->get_proc_info();
 
1729
  session->set_proc_info("removing tmp table");
 
1730
 
 
1731
  // Release latches since this can take a long time
 
1732
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
1733
 
 
1734
  if (cursor)
 
1735
  {
 
1736
    if (db_stat)
 
1737
    {
 
1738
      cursor->closeMarkForDelete(s->getTableName());
 
1739
    }
 
1740
 
 
1741
    TableIdentifier identifier(s->getSchemaName(), s->getTableName(), s->getTableName());
 
1742
    s->db_type()->doDropTable(*session, identifier);
 
1743
 
 
1744
    delete cursor;
 
1745
  }
 
1746
 
 
1747
  /* free blobs */
 
1748
  for (Field **ptr= field ; *ptr ; ptr++)
 
1749
  {
 
1750
    (*ptr)->free();
 
1751
  }
 
1752
  free_io_cache();
 
1753
 
 
1754
  own_root.free_root(MYF(0)); /* the table is allocated in its own root */
 
1755
  session->set_proc_info(save_proc_info);
 
1756
}
 
1757
 
 
1758
my_bitmap_map *Table::use_all_columns(MyBitmap *bitmap)
 
1759
{
 
1760
  my_bitmap_map *old= bitmap->getBitmap();
 
1761
  bitmap->setBitmap(s->all_set.getBitmap());
1418
1762
  return old;
1419
1763
}
1420
1764
 
1421
 
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
 
1765
void Table::restore_column_map(my_bitmap_map *old)
1422
1766
{
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
 
  }
 
1767
  read_set->setBitmap(old);
1434
1768
}
1435
1769
 
1436
1770
uint32_t Table::find_shortest_key(const key_map *usable_keys)
1439
1773
  uint32_t best= MAX_KEY;
1440
1774
  if (usable_keys->any())
1441
1775
  {
1442
 
    for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
 
1776
    for (uint32_t nr= 0; nr < s->sizeKeys() ; nr++)
1443
1777
    {
1444
1778
      if (usable_keys->test(nr))
1445
1779
      {
1466
1800
{
1467
1801
  for (; *ptr ; ptr++)
1468
1802
  {
1469
 
    if ((*ptr)->cmp_offset(getShare()->rec_buff_length))
 
1803
    if ((*ptr)->cmp_offset(s->rec_buff_length))
1470
1804
      return true;
1471
1805
  }
1472
1806
  return false;
1473
1807
}
1474
1808
 
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
 
 
 
1809
/* Return false if row hasn't changed */
 
1810
 
 
1811
bool Table::compare_record()
 
1812
{
 
1813
  if (s->blob_fields + s->varchar_fields == 0)
 
1814
    return memcmp(this->record[0], this->record[1], (size_t) s->getRecordLength());
 
1815
  
1536
1816
  /* Compare null bits */
1537
 
  if (memcmp(null_flags, null_flags + getShare()->rec_buff_length, getShare()->null_bytes))
 
1817
  if (memcmp(null_flags, null_flags + s->rec_buff_length, s->null_bytes))
1538
1818
    return true; /* Diff in NULL value */
1539
1819
 
1540
1820
  /* Compare updated fields */
1541
1821
  for (Field **ptr= field ; *ptr ; ptr++)
1542
1822
  {
1543
 
    if (isWriteSet((*ptr)->position()) &&
1544
 
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
 
1823
    if (isWriteSet((*ptr)->field_index) &&
 
1824
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
1545
1825
      return true;
1546
1826
  }
1547
1827
  return false;
1553
1833
 */
1554
1834
void Table::storeRecord()
1555
1835
{
1556
 
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1836
  memcpy(record[1], record[0], (size_t) s->getRecordLength());
1557
1837
}
1558
1838
 
1559
1839
/*
1562
1842
 */
1563
1843
void Table::storeRecordAsInsert()
1564
1844
{
1565
 
  assert(insert_values.size() >= getShare()->getRecordLength());
1566
 
  memcpy(&insert_values[0], getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1845
  memcpy(insert_values, record[0], (size_t) s->getRecordLength());
1567
1846
}
1568
1847
 
1569
1848
/*
1572
1851
 */
1573
1852
void Table::storeRecordAsDefault()
1574
1853
{
1575
 
  memcpy(getMutableShare()->getDefaultValues(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1854
  memcpy(s->getDefaultValues(), record[0], (size_t) s->getRecordLength());
1576
1855
}
1577
1856
 
1578
1857
/*
1581
1860
 */
1582
1861
void Table::restoreRecord()
1583
1862
{
1584
 
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) getShare()->getRecordLength());
 
1863
  memcpy(record[0], record[1], (size_t) s->getRecordLength());
1585
1864
}
1586
1865
 
1587
1866
/*
1590
1869
 */
1591
1870
void Table::restoreRecordAsDefault()
1592
1871
{
1593
 
  memcpy(getInsertRecord(), getMutableShare()->getDefaultValues(), (size_t) getShare()->getRecordLength());
 
1872
  memcpy(record[0], s->getDefaultValues(), (size_t) s->getRecordLength());
1594
1873
}
1595
1874
 
1596
1875
/*
1600
1879
void Table::emptyRecord()
1601
1880
{
1602
1881
  restoreRecordAsDefault();
1603
 
  memset(null_flags, 255, getShare()->null_bytes);
 
1882
  memset(null_flags, 255, s->null_bytes);
1604
1883
}
1605
1884
 
1606
1885
Table::Table() : 
 
1886
  s(NULL),
1607
1887
  field(NULL),
1608
1888
  cursor(NULL),
1609
1889
  next(NULL),
1612
1892
  write_set(NULL),
1613
1893
  tablenr(0),
1614
1894
  db_stat(0),
1615
 
  def_read_set(),
1616
 
  def_write_set(),
1617
 
  tmp_set(),
1618
1895
  in_use(NULL),
 
1896
  insert_values(NULL),
1619
1897
  key_info(NULL),
1620
1898
  next_number_field(NULL),
1621
1899
  found_next_number_field(NULL),
1622
1900
  timestamp_field(NULL),
1623
1901
  pos_in_table_list(NULL),
1624
1902
  group(NULL),
 
1903
  alias(NULL),
1625
1904
  null_flags(NULL),
1626
1905
  lock_position(0),
1627
1906
  lock_data_start(0),
1647
1926
  query_id(0),
1648
1927
  quick_condition_rows(0),
1649
1928
  timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
1650
 
  map(0)
 
1929
  map(0),
 
1930
  is_placeholder_created(0)
1651
1931
{
 
1932
  memset(&def_read_set, 0, sizeof(MyBitmap)); /**< Default read set of columns */
 
1933
  memset(&def_write_set, 0, sizeof(MyBitmap)); /**< Default write set of columns */
 
1934
  memset(&tmp_set, 0, sizeof(MyBitmap)); /* Not sure about this... */
 
1935
 
1652
1936
  record[0]= (unsigned char *) 0;
1653
1937
  record[1]= (unsigned char *) 0;
1654
1938
 
1666
1950
 
1667
1951
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
1668
1952
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
 
1953
 
 
1954
  memset(&mem_root, 0, sizeof(memory::Root));
 
1955
  memset(&sort, 0, sizeof(filesort_info_st));
1669
1956
}
1670
1957
 
1671
1958
/*****************************************************************************
1688
1975
  */
1689
1976
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
1690
1977
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
1691
 
                  error, getShare()->getPath());
 
1978
                  error, s->getPath());
1692
1979
  print_error(error, MYF(0));
1693
1980
 
1694
1981
  return 1;
1711
1998
  tablenr= table_number;
1712
1999
  map= (table_map) 1 << table_number;
1713
2000
  force_index= table_list->force_index;
1714
 
  covering_keys= getShare()->keys_for_keyread;
 
2001
  covering_keys= s->keys_for_keyread;
1715
2002
  merge_keys.reset();
1716
2003
}
1717
2004
 
1731
2018
  return false;
1732
2019
}
1733
2020
 
1734
 
 
1735
 
void Table::filesort_free_buffers(bool full)
1736
 
{
1737
 
  if (sort.record_pointers)
1738
 
  {
1739
 
    free((unsigned char*) sort.record_pointers);
1740
 
    sort.record_pointers=0;
1741
 
  }
1742
 
  if (full)
1743
 
  {
1744
 
    if (sort.sort_keys )
1745
 
    {
1746
 
      if ((unsigned char*) sort.sort_keys)
1747
 
        free((unsigned char*) sort.sort_keys);
1748
 
      sort.sort_keys= 0;
1749
 
    }
1750
 
    if (sort.buffpek)
1751
 
    {
1752
 
      if ((unsigned char*) sort.buffpek)
1753
 
        free((unsigned char*) sort.buffpek);
1754
 
      sort.buffpek= 0;
1755
 
      sort.buffpek_len= 0;
1756
 
    }
1757
 
  }
1758
 
 
1759
 
  if (sort.addon_buf)
1760
 
  {
1761
 
    free((char *) sort.addon_buf);
1762
 
    free((char *) sort.addon_field);
1763
 
    sort.addon_buf=0;
1764
 
    sort.addon_field=0;
1765
 
  }
1766
 
}
1767
 
 
1768
2021
} /* namespace drizzled */