~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: mordred
  • Date: 2010-08-21 03:56:04 UTC
  • mto: (1725.1.5 build)
  • mto: This revision was merged to the branch mainline in revision 1726.
  • Revision ID: mordred@orisndriz09-20100821035604-da3nk2jsfti7o5d2
Added a valgrind suppression for the myisam keycache thing.

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 */
18
18
 
19
 
#include <config.h>
 
19
#include "config.h"
20
20
 
21
21
#include <float.h>
22
22
#include <fcntl.h>
28
28
#include <drizzled/error.h>
29
29
#include <drizzled/gettext.h>
30
30
 
31
 
#include <drizzled/plugin/transactional_storage_engine.h>
32
 
#include <drizzled/plugin/authorization.h>
 
31
#include "drizzled/plugin/transactional_storage_engine.h"
 
32
#include "drizzled/plugin/authorization.h"
33
33
#include <drizzled/nested_join.h>
34
34
#include <drizzled/sql_parse.h>
35
35
#include <drizzled/item/sum.h>
42
42
#include <drizzled/field/double.h>
43
43
#include <drizzled/unireg.h>
44
44
#include <drizzled/message/table.pb.h>
45
 
#include <drizzled/sql_table.h>
46
 
#include <drizzled/charset.h>
47
 
#include <drizzled/internal/m_string.h>
48
 
#include <plugin/myisam/myisam.h>
49
 
#include <drizzled/plugin/storage_engine.h>
 
45
#include "drizzled/sql_table.h"
 
46
#include "drizzled/charset.h"
 
47
#include "drizzled/internal/m_string.h"
 
48
#include "plugin/myisam/myisam.h"
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>
61
 
 
62
 
#include <drizzled/table_proto.h>
63
 
#include <drizzled/typelib.h>
 
57
#include "drizzled/table_share_instance.h"
 
58
 
 
59
#include "drizzled/table_proto.h"
64
60
 
65
61
using namespace std;
66
62
 
67
63
namespace drizzled
68
64
{
69
65
 
 
66
extern pid_t current_pid;
70
67
extern plugin::StorageEngine *heap_engine;
71
68
extern plugin::StorageEngine *myisam_engine;
72
69
 
73
70
/* Functions defined in this cursor */
74
71
 
 
72
void open_table_error(TableShare *share, int error, int db_errno,
 
73
                      myf errortype, int errarg);
 
74
 
75
75
/*************************************************************************/
76
76
 
77
77
// @note this should all be the destructor
81
81
 
82
82
  if (db_stat)
83
83
    error= cursor->close();
84
 
  _alias.clear();
85
 
 
 
84
  free((char*) alias);
 
85
  alias= NULL;
86
86
  if (field)
87
87
  {
88
88
    for (Field **ptr=field ; *ptr ; ptr++)
91
91
    }
92
92
    field= 0;
93
93
  }
94
 
  safe_delete(cursor);
 
94
  delete cursor;
 
95
  cursor= 0;                            /* For easier errorchecking */
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;
197
202
 
198
203
/* Deallocate temporary blob storage */
199
204
 
200
 
void free_blobs(Table *table)
 
205
void free_blobs(register Table *table)
201
206
{
202
207
  uint32_t *ptr, *end;
203
208
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
223
228
    
224
229
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
225
230
 
226
 
  List<String>::iterator it(strings.begin());
 
231
  List_iterator<String> it(strings);
227
232
  String *tmp;
228
233
  for (uint32_t i= 0; (tmp= it++); i++)
229
234
  {
239
244
 
240
245
        /* Check that the integer is in the internal */
241
246
 
242
 
int set_zone(int nr, int min_zone, int max_zone)
 
247
int set_zone(register int nr, int min_zone, int max_zone)
243
248
{
244
249
  if (nr<=min_zone)
245
250
    return (min_zone);
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;
323
361
}
324
362
 
325
363
/*
 
364
  Check if database name is valid
 
365
 
 
366
  SYNPOSIS
 
367
    check_db_name()
 
368
    org_name            Name of database and length
 
369
 
 
370
  RETURN
 
371
    false error
 
372
    true ok
 
373
*/
 
374
 
 
375
bool check_db_name(Session *session, SchemaIdentifier &schema_identifier)
 
376
{
 
377
  if (not plugin::Authorization::isAuthorized(session->getSecurityContext(), schema_identifier))
 
378
  {
 
379
    return false;
 
380
  }
 
381
 
 
382
  return schema_identifier.isValid();
 
383
}
 
384
 
 
385
/*
326
386
  Allow anything as a table name, as long as it doesn't contain an
327
387
  ' ' at the end
328
388
  returns 1 on error
392
452
    bitmap_clear_all(&table->def_read_set);
393
453
    bitmap_clear_all(&table->def_write_set);
394
454
  */
395
 
  def_read_set.reset();
396
 
  def_write_set.reset();
397
 
  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);
398
458
}
399
459
 
400
460
 
411
471
{
412
472
 
413
473
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
414
 
      getShare()->hasPrimaryKey())
 
474
      s->hasPrimaryKey())
415
475
  {
416
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
476
    mark_columns_used_by_index_no_reset(s->getPrimaryKey());
417
477
  }
418
478
  return;
419
479
}
431
491
 
432
492
void Table::mark_columns_used_by_index(uint32_t index)
433
493
{
434
 
  boost::dynamic_bitset<> *bitmap= &tmp_set;
 
494
  MyBitmap *bitmap= &tmp_set;
435
495
 
436
496
  (void) cursor->extra(HA_EXTRA_KEYREAD);
437
 
  bitmap->reset();
438
 
  mark_columns_used_by_index_no_reset(index, *bitmap);
439
 
  column_bitmaps_set(*bitmap, *bitmap);
 
497
  bitmap->clearAll();
 
498
  mark_columns_used_by_index_no_reset(index, bitmap);
 
499
  column_bitmaps_set(bitmap, bitmap);
440
500
  return;
441
501
}
442
502
 
468
528
 
469
529
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
470
530
{
471
 
    mark_columns_used_by_index_no_reset(index, *read_set);
 
531
    mark_columns_used_by_index_no_reset(index, read_set);
472
532
}
473
533
 
474
 
 
475
534
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
476
 
                                                boost::dynamic_bitset<>& bitmap)
 
535
                                                MyBitmap *bitmap)
477
536
{
478
537
  KeyPartInfo *key_part= key_info[index].key_part;
479
 
  KeyPartInfo *key_part_end= (key_part + key_info[index].key_parts);
480
 
  for (; key_part != key_part_end; key_part++)
481
 
  {
482
 
    if (! bitmap.empty())
483
 
      bitmap.set(key_part->fieldnr-1);
484
 
  }
 
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);
485
542
}
486
543
 
487
544
 
500
557
    We must set bit in read set as update_auto_increment() is using the
501
558
    store() to check overflow of auto_increment values
502
559
  */
503
 
  setReadSet(found_next_number_field->position());
504
 
  setWriteSet(found_next_number_field->position());
505
 
  if (getShare()->next_number_keypart)
506
 
    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);
507
564
}
508
565
 
509
566
 
534
591
    be able to do an delete
535
592
 
536
593
  */
537
 
  if (not getShare()->hasPrimaryKey())
 
594
  if (not s->hasPrimaryKey())
538
595
  {
539
596
    /* fallback to use all columns in the table to identify row */
540
597
    use_all_columns();
541
598
    return;
542
599
  }
543
600
  else
544
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
601
    mark_columns_used_by_index_no_reset(s->getPrimaryKey());
545
602
 
546
603
  /* If we the engine wants all predicates we mark all keys */
547
604
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
550
607
    for (reg_field= field ; *reg_field ; reg_field++)
551
608
    {
552
609
      if ((*reg_field)->flags & PART_KEY_FLAG)
553
 
        setReadSet((*reg_field)->position());
 
610
        setReadSet((*reg_field)->field_index);
554
611
    }
555
612
  }
556
613
}
582
639
    the primary key, the hidden primary key or all columns to be
583
640
    able to do an update
584
641
  */
585
 
  if (not getShare()->hasPrimaryKey())
 
642
  if (not s->hasPrimaryKey())
586
643
  {
587
644
    /* fallback to use all columns in the table to identify row */
588
645
    use_all_columns();
589
646
    return;
590
647
  }
591
648
  else
592
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
649
    mark_columns_used_by_index_no_reset(s->getPrimaryKey());
593
650
 
594
651
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
595
652
  {
599
656
    {
600
657
      /* Merge keys is all keys that had a column refered to in the query */
601
658
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
602
 
        setReadSet((*reg_field)->position());
 
659
        setReadSet((*reg_field)->field_index);
603
660
    }
604
661
  }
605
662
 
637
694
  return length;
638
695
}
639
696
 
640
 
void Table::setVariableWidth(void)
641
 
{
642
 
  assert(in_use);
643
 
  if (in_use && in_use->getLex()->sql_command == SQLCOM_CREATE_TABLE)
644
 
  {
645
 
    getMutableShare()->setVariableWidth();
646
 
    return;
647
 
  }
648
 
 
649
 
  assert(0); // Programming error, you can't set this on a plain old Table.
650
 
}
651
 
 
652
697
/****************************************************************************
653
698
 Functions for creating temporary tables.
654
699
****************************************************************************/
686
731
  */
687
732
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
688
733
      (org_field->flags & BLOB_FLAG))
689
 
  {
690
 
    table->setVariableWidth();
691
734
    new_field= new Field_varstring(convert_blob_length,
692
735
                                   org_field->maybe_null(),
693
 
                                   org_field->field_name,
 
736
                                   org_field->field_name, table->getMutableShare(),
694
737
                                   org_field->charset());
695
 
  }
696
738
  else
697
 
  {
698
739
    new_field= org_field->new_field(session->mem_root, table,
699
740
                                    table == org_field->getTable());
700
 
  }
701
741
  if (new_field)
702
742
  {
703
743
    new_field->init(table);
750
790
 
751
791
Table *
752
792
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
753
 
                 Order *group, bool distinct, bool save_sum_fields,
 
793
                 order_st *group, bool distinct, bool save_sum_fields,
754
794
                 uint64_t select_options, ha_rows rows_limit,
755
795
                 const char *table_alias)
756
796
{
757
797
  memory::Root *mem_root_save;
 
798
  Table *table;
758
799
  uint  i,field_count,null_count,null_pack_length;
759
800
  uint32_t  copy_func_count= param->func_count;
760
801
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
764
805
  bool  using_unique_constraint= false;
765
806
  bool  use_packed_rows= true;
766
807
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
767
 
  unsigned char *pos, *group_buff;
 
808
  unsigned char *pos, *group_buff, *bitmaps;
768
809
  unsigned char *null_flags;
769
810
  Field **reg_field, **from_field, **default_field;
770
811
  CopyField *copy= 0;
784
825
    {
785
826
      group= 0;                                 // Can't use group key
786
827
    }
787
 
    else for (Order *tmp=group ; tmp ; tmp=tmp->next)
 
828
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
788
829
    {
789
830
      /*
790
831
        marker == 4 means two things:
817
858
    copy_func_count+= param->sum_func_count;
818
859
  }
819
860
 
820
 
  table::Singular *table;
821
 
  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.
822
862
 
823
 
  if (not table->getMemRoot()->multi_alloc_root(0,
 
863
  if (not share->getMemRoot()->multi_alloc_root(0,
824
864
                                                &default_field, sizeof(Field*) * (field_count),
825
865
                                                &from_field, sizeof(Field*)*field_count,
826
866
                                                &copy_func, sizeof(*copy_func)*(copy_func_count+1),
829
869
                                                &param->start_recinfo, sizeof(*param->recinfo)*(field_count*2+4),
830
870
                                                &group_buff, (group && ! using_unique_constraint ?
831
871
                                                              param->group_length : 0),
 
872
                                                &bitmaps, bitmap_buffer_size(field_count)*2,
832
873
                                                NULL))
833
874
  {
834
875
    return NULL;
841
882
  param->items_to_copy= copy_func;
842
883
  /* make table according to fields */
843
884
 
 
885
  table= share->getTable();
 
886
 
844
887
  memset(default_field, 0, sizeof(Field*) * (field_count));
845
888
  memset(from_field, 0, sizeof(Field*)*field_count);
846
889
 
847
890
  mem_root_save= session->mem_root;
848
891
  session->mem_root= table->getMemRoot();
849
892
 
850
 
  table->getMutableShare()->setFields(field_count+1);
851
 
  table->setFields(table->getMutableShare()->getFields(true));
852
 
  reg_field= table->getMutableShare()->getFields(true);
853
 
  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;
854
897
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
855
898
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
856
899
  table->map=1;
861
904
  table->covering_keys.reset();
862
905
  table->keys_in_use_for_query.reset();
863
906
 
864
 
  table->getMutableShare()->blob_field.resize(field_count+1);
865
 
  uint32_t *blob_field= &table->getMutableShare()->blob_field[0];
866
 
  table->getMutableShare()->db_low_byte_first=1;                // True for HEAP and MyISAM
867
 
  table->getMutableShare()->table_charset= param->table_charset;
868
 
  table->getMutableShare()->keys_for_keyread.reset();
869
 
  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();
870
915
 
871
916
  /* Calculate which type of fields we will store in the temporary table */
872
917
 
874
919
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
875
920
  param->using_indirect_summary_function= 0;
876
921
 
877
 
  List<Item>::iterator li(fields.begin());
 
922
  List_iterator_fast<Item> li(fields);
878
923
  Item *item;
879
924
  Field **tmp_from_field=from_field;
880
925
  while ((item=li++))
943
988
            */
944
989
            (*argp)->maybe_null=1;
945
990
          }
946
 
          new_field->setPosition(fieldnr++);
 
991
          new_field->field_index= fieldnr++;
947
992
        }
948
993
      }
949
994
    }
990
1035
        group_null_items++;
991
1036
        new_field->flags|= GROUP_FLAG;
992
1037
      }
993
 
      new_field->setPosition(fieldnr++);
 
1038
      new_field->field_index= fieldnr++;
994
1039
      *(reg_field++)= new_field;
995
1040
    }
996
1041
    if (!--hidden_field_count)
1013
1058
  field_count= fieldnr;
1014
1059
  *reg_field= 0;
1015
1060
  *blob_field= 0;                               // End marker
1016
 
  table->getMutableShare()->setFieldSize(field_count);
 
1061
  share->fields= field_count;
1017
1062
 
1018
1063
  /* If result table is small; use a heap */
1019
1064
  /* future: storage engine selection can be made dynamic? */
1020
1065
  if (blob_count || using_unique_constraint || 
1021
 
      (session->getLex()->select_lex.options & SELECT_BIG_RESULT) ||
1022
 
      (session->getLex()->current_select->olap == ROLLUP_TYPE) ||
 
1066
      (session->lex->select_lex.options & SELECT_BIG_RESULT) ||
 
1067
      (session->lex->current_select->olap == ROLLUP_TYPE) ||
1023
1068
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
1024
1069
  {
1025
 
    table->getMutableShare()->storage_engine= myisam_engine;
1026
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
1070
    share->storage_engine= myisam_engine;
 
1071
    table->cursor= share->db_type()->getCursor(*share);
1027
1072
    if (group &&
1028
1073
        (param->group_parts > table->cursor->getEngine()->max_key_parts() ||
1029
1074
         param->group_length > table->cursor->getEngine()->max_key_length()))
1033
1078
  }
1034
1079
  else
1035
1080
  {
1036
 
    table->getMutableShare()->storage_engine= heap_engine;
1037
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
1081
    share->storage_engine= heap_engine;
 
1082
    table->cursor= share->db_type()->getCursor(*share);
1038
1083
  }
1039
1084
  if (! table->cursor)
1040
1085
    goto err;
1043
1088
  if (! using_unique_constraint)
1044
1089
    reclength+= group_null_items;       // null flag is stored separately
1045
1090
 
1046
 
  table->getMutableShare()->blob_fields= blob_count;
 
1091
  share->blob_fields= blob_count;
1047
1092
  if (blob_count == 0)
1048
1093
  {
1049
1094
    /* We need to ensure that first byte is not 0 for the delete link */
1062
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)))
1063
1108
    use_packed_rows= 1;
1064
1109
 
1065
 
  table->getMutableShare()->setRecordLength(reclength);
 
1110
  share->setRecordLength(reclength);
1066
1111
  {
1067
1112
    uint32_t alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
1068
 
    table->getMutableShare()->rec_buff_length= alloc_length;
 
1113
    share->rec_buff_length= alloc_length;
1069
1114
    if (!(table->record[0]= (unsigned char*) table->alloc_root(alloc_length*2)))
1070
1115
    {
1071
1116
      goto err;
1072
1117
    }
1073
1118
    table->record[1]= table->getInsertRecord()+alloc_length;
1074
 
    table->getMutableShare()->resizeDefaultValues(alloc_length);
 
1119
    share->resizeDefaultValues(alloc_length);
1075
1120
  }
1076
1121
  copy_func[0]= 0;                              // End marker
1077
1122
  param->func_count= copy_func - param->items_to_copy;
1078
1123
 
1079
 
  table->setup_tmp_table_column_bitmaps();
 
1124
  table->setup_tmp_table_column_bitmaps(bitmaps);
1080
1125
 
1081
1126
  recinfo=param->start_recinfo;
1082
1127
  null_flags=(unsigned char*) table->getInsertRecord();
1090
1135
    memset(null_flags, 255, null_pack_length);  // Set null fields
1091
1136
 
1092
1137
    table->null_flags= (unsigned char*) table->getInsertRecord();
1093
 
    table->getMutableShare()->null_fields= null_count+ hidden_null_count;
1094
 
    table->getMutableShare()->null_bytes= null_pack_length;
 
1138
    share->null_fields= null_count+ hidden_null_count;
 
1139
    share->null_bytes= null_pack_length;
1095
1140
  }
1096
1141
  null_count= (blob_count == 0) ? 1 : 0;
1097
1142
  hidden_field_count=param->hidden_field_count;
1182
1227
  }
1183
1228
  else
1184
1229
  {
1185
 
    max_rows= (uint64_t) (((table->getMutableShare()->db_type() == heap_engine) ?
 
1230
    max_rows= (uint64_t) (((share->db_type() == heap_engine) ?
1186
1231
                           min(session->variables.tmp_table_size,
1187
1232
                               session->variables.max_heap_table_size) :
1188
1233
                           session->variables.tmp_table_size) /
1189
 
                          table->getMutableShare()->getRecordLength());
 
1234
                          share->getRecordLength());
1190
1235
  }
1191
1236
 
1192
1237
  set_if_bigger(max_rows, (uint64_t)1); // For dummy start options
1196
1241
  */
1197
1242
  set_if_smaller(max_rows, rows_limit);
1198
1243
 
1199
 
  table->getMutableShare()->setMaxRows(max_rows);
 
1244
  share->setMaxRows(max_rows);
1200
1245
 
1201
1246
  param->end_write_records= rows_limit;
1202
1247
 
1206
1251
  {
1207
1252
    table->group=group;                         /* Table is grouped by key */
1208
1253
    param->group_buff=group_buff;
1209
 
    table->getMutableShare()->keys=1;
1210
 
    table->getMutableShare()->uniques= test(using_unique_constraint);
 
1254
    share->keys=1;
 
1255
    share->uniques= test(using_unique_constraint);
1211
1256
    table->key_info=keyinfo;
1212
1257
    keyinfo->key_part=key_part_info;
1213
1258
    keyinfo->flags=HA_NOSAME;
1216
1261
    keyinfo->rec_per_key= 0;
1217
1262
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1218
1263
    keyinfo->name= (char*) "group_key";
1219
 
    Order *cur_group= group;
 
1264
    order_st *cur_group= group;
1220
1265
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
1221
1266
    {
1222
1267
      Field *field=(*cur_group->item)->get_tmp_table_field();
1278
1323
        indexes on blobs with arbitrary length. Such indexes cannot be
1279
1324
        used for lookups.
1280
1325
      */
1281
 
      table->getMutableShare()->uniques= 1;
 
1326
      share->uniques= 1;
1282
1327
    }
1283
1328
    null_pack_length-=hidden_null_pack_length;
1284
1329
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
1285
 
                         (table->getMutableShare()->uniques ? test(null_pack_length) : 0));
 
1330
                         (share->uniques ? test(null_pack_length) : 0));
1286
1331
    table->distinct= 1;
1287
 
    table->getMutableShare()->keys= 1;
 
1332
    share->keys= 1;
1288
1333
    if (!(key_part_info= (KeyPartInfo*)
1289
1334
         table->alloc_root(keyinfo->key_parts * sizeof(KeyPartInfo))))
1290
1335
      goto err;
1302
1347
      blobs can distinguish NULL from 0. This extra field is not needed
1303
1348
      when we do not use UNIQUE indexes for blobs.
1304
1349
    */
1305
 
    if (null_pack_length && table->getMutableShare()->uniques)
 
1350
    if (null_pack_length && share->uniques)
1306
1351
    {
1307
1352
      key_part_info->null_bit= 0;
1308
1353
      key_part_info->offset=hidden_null_pack_length;
1309
1354
      key_part_info->length=null_pack_length;
1310
 
      table->setVariableWidth();
1311
1355
      key_part_info->field= new Field_varstring(table->getInsertRecord(),
1312
1356
                                                (uint32_t) key_part_info->length,
1313
1357
                                                0,
1314
1358
                                                (unsigned char*) 0,
1315
1359
                                                (uint32_t) 0,
1316
1360
                                                NULL,
 
1361
                                                table->getMutableShare(),
1317
1362
                                                &my_charset_bin);
1318
1363
      if (!key_part_info->field)
1319
1364
        goto err;
1357
1402
 
1358
1403
  if (session->is_fatal_error)                          // If end of memory
1359
1404
    goto err;
1360
 
  table->getMutableShare()->db_record_offset= 1;
1361
 
  if (table->getShare()->db_type() == myisam_engine)
 
1405
  share->db_record_offset= 1;
 
1406
  if (share->db_type() == myisam_engine)
1362
1407
  {
1363
1408
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
1364
1409
                                       &param->recinfo, select_options))
1381
1426
 
1382
1427
/****************************************************************************/
1383
1428
 
1384
 
void Table::column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
1385
 
                               boost::dynamic_bitset<>& write_set_arg)
1386
 
{
1387
 
  read_set= &read_set_arg;
1388
 
  write_set= &write_set_arg;
1389
 
}
1390
 
 
1391
 
 
1392
 
const boost::dynamic_bitset<> Table::use_all_columns(boost::dynamic_bitset<>& in_map)
1393
 
{
1394
 
  const boost::dynamic_bitset<> old= in_map;
1395
 
  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
                             s->getTableName(),
 
1569
                             O_RDWR,
 
1570
                             HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
 
1571
  {
 
1572
    print_error(error, MYF(0));
 
1573
    db_stat= 0;
 
1574
    return true;
 
1575
  }
 
1576
  (void) cursor->extra(HA_EXTRA_QUICK);         /* Faster */
 
1577
  return false;
 
1578
}
 
1579
 
 
1580
 
 
1581
/*
 
1582
  Create MyISAM temporary table
 
1583
 
 
1584
  SYNOPSIS
 
1585
    create_myisam_tmp_table()
 
1586
      keyinfo         Description of the index (there is always one index)
 
1587
      start_recinfo   MyISAM's column descriptions
 
1588
      recinfo INOUT   End of MyISAM's column descriptions
 
1589
      options         Option bits
 
1590
 
 
1591
  DESCRIPTION
 
1592
    Create a MyISAM temporary table according to passed description. The is
 
1593
    assumed to have one unique index or constraint.
 
1594
 
 
1595
    The passed array or MI_COLUMNDEF structures must have this form:
 
1596
 
 
1597
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
 
1598
         when there are many nullable columns)
 
1599
      2. Table columns
 
1600
      3. One free MI_COLUMNDEF element (*recinfo points here)
 
1601
 
 
1602
    This function may use the free element to create hash column for unique
 
1603
    constraint.
 
1604
 
 
1605
   RETURN
 
1606
     false - OK
 
1607
     true  - Error
 
1608
*/
 
1609
 
 
1610
bool Table::create_myisam_tmp_table(KeyInfo *keyinfo,
 
1611
                                    MI_COLUMNDEF *start_recinfo,
 
1612
                                    MI_COLUMNDEF **recinfo,
 
1613
                                    uint64_t options)
 
1614
{
 
1615
  int error;
 
1616
  MI_KEYDEF keydef;
 
1617
  MI_UNIQUEDEF uniquedef;
 
1618
  TableShare *share= s;
 
1619
 
 
1620
  if (share->sizeKeys())
 
1621
  {                                             // Get keys for ni_create
 
1622
    bool using_unique_constraint= false;
 
1623
    HA_KEYSEG *seg= (HA_KEYSEG*) this->mem_root.alloc_root(sizeof(*seg) * keyinfo->key_parts);
 
1624
    if (not seg)
 
1625
      return true;
 
1626
 
 
1627
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
 
1628
    if (keyinfo->key_length >= cursor->getEngine()->max_key_length() ||
 
1629
        keyinfo->key_parts > cursor->getEngine()->max_key_parts() ||
 
1630
        share->uniques)
 
1631
    {
 
1632
      /* Can't create a key; Make a unique constraint instead of a key */
 
1633
      share->keys=    0;
 
1634
      share->uniques= 1;
 
1635
      using_unique_constraint= true;
 
1636
      memset(&uniquedef, 0, sizeof(uniquedef));
 
1637
      uniquedef.keysegs=keyinfo->key_parts;
 
1638
      uniquedef.seg=seg;
 
1639
      uniquedef.null_are_equal=1;
 
1640
 
 
1641
      /* Create extra column for hash value */
 
1642
      memset(*recinfo, 0, sizeof(**recinfo));
 
1643
      (*recinfo)->type= FIELD_CHECK;
 
1644
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
 
1645
      (*recinfo)++;
 
1646
      share->setRecordLength(share->getRecordLength() + MI_UNIQUE_HASH_LENGTH);
 
1647
    }
 
1648
    else
 
1649
    {
 
1650
      /* Create an unique key */
 
1651
      memset(&keydef, 0, sizeof(keydef));
 
1652
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
 
1653
      keydef.keysegs=  keyinfo->key_parts;
 
1654
      keydef.seg= seg;
 
1655
    }
 
1656
    for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
 
1657
    {
 
1658
      Field *key_field=keyinfo->key_part[i].field;
 
1659
      seg->flag=     0;
 
1660
      seg->language= key_field->charset()->number;
 
1661
      seg->length=   keyinfo->key_part[i].length;
 
1662
      seg->start=    keyinfo->key_part[i].offset;
 
1663
      if (key_field->flags & BLOB_FLAG)
 
1664
      {
 
1665
        seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
 
1666
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
 
1667
        seg->bit_start= (uint8_t)(key_field->pack_length()
 
1668
                                  - share->blob_ptr_size);
 
1669
        seg->flag= HA_BLOB_PART;
 
1670
        seg->length= 0;                 // Whole blob in unique constraint
 
1671
      }
 
1672
      else
 
1673
      {
 
1674
        seg->type= keyinfo->key_part[i].type;
 
1675
      }
 
1676
      if (!(key_field->flags & NOT_NULL_FLAG))
 
1677
      {
 
1678
        seg->null_bit= key_field->null_bit;
 
1679
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) getInsertRecord());
 
1680
        /*
 
1681
          We are using a GROUP BY on something that contains NULL
 
1682
          In this case we have to tell MyISAM that two NULL should
 
1683
          on INSERT be regarded at the same value
 
1684
        */
 
1685
        if (! using_unique_constraint)
 
1686
          keydef.flag|= HA_NULL_ARE_EQUAL;
 
1687
      }
 
1688
    }
 
1689
  }
 
1690
  MI_CREATE_INFO create_info;
 
1691
 
 
1692
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
1693
      OPTION_BIG_TABLES)
 
1694
    create_info.data_file_length= ~(uint64_t) 0;
 
1695
 
 
1696
  if ((error= mi_create(share->getTableName(), share->sizeKeys(), &keydef,
 
1697
                        (uint32_t) (*recinfo-start_recinfo),
 
1698
                        start_recinfo,
 
1699
                        share->uniques, &uniquedef,
 
1700
                        &create_info,
 
1701
                        HA_CREATE_TMP_TABLE)))
 
1702
  {
 
1703
    print_error(error, MYF(0));
 
1704
    db_stat= 0;
 
1705
 
 
1706
    return true;
 
1707
  }
 
1708
  in_use->status_var.created_tmp_disk_tables++;
 
1709
  share->db_record_offset= 1;
 
1710
  return false;
 
1711
}
 
1712
 
 
1713
 
 
1714
void Table::free_tmp_table(Session *session)
 
1715
{
 
1716
  memory::Root own_root= mem_root;
 
1717
  const char *save_proc_info;
 
1718
 
 
1719
  save_proc_info= session->get_proc_info();
 
1720
  session->set_proc_info("removing tmp table");
 
1721
 
 
1722
  // Release latches since this can take a long time
 
1723
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
1724
 
 
1725
  if (cursor)
 
1726
  {
 
1727
    if (db_stat)
 
1728
    {
 
1729
      cursor->closeMarkForDelete(s->getTableName());
 
1730
    }
 
1731
 
 
1732
    TableIdentifier identifier(s->getSchemaName(), s->getTableName(), s->getTableName());
 
1733
    s->db_type()->doDropTable(*session, identifier);
 
1734
 
 
1735
    delete cursor;
 
1736
  }
 
1737
 
 
1738
  /* free blobs */
 
1739
  for (Field **ptr= field ; *ptr ; ptr++)
 
1740
  {
 
1741
    (*ptr)->free();
 
1742
  }
 
1743
  free_io_cache();
 
1744
 
 
1745
  own_root.free_root(MYF(0)); /* the table is allocated in its own root */
 
1746
  session->set_proc_info(save_proc_info);
 
1747
}
 
1748
 
 
1749
my_bitmap_map *Table::use_all_columns(MyBitmap *bitmap)
 
1750
{
 
1751
  my_bitmap_map *old= bitmap->getBitmap();
 
1752
  bitmap->setBitmap(s->all_set.getBitmap());
1396
1753
  return old;
1397
1754
}
1398
1755
 
1399
 
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
 
1756
void Table::restore_column_map(my_bitmap_map *old)
1400
1757
{
1401
 
  for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
1402
 
  {
1403
 
    if (old.test(i))
1404
 
    {
1405
 
      read_set->set(i);
1406
 
    }
1407
 
    else
1408
 
    {
1409
 
      read_set->reset(i);
1410
 
    }
1411
 
  }
 
1758
  read_set->setBitmap(old);
1412
1759
}
1413
1760
 
1414
1761
uint32_t Table::find_shortest_key(const key_map *usable_keys)
1417
1764
  uint32_t best= MAX_KEY;
1418
1765
  if (usable_keys->any())
1419
1766
  {
1420
 
    for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
 
1767
    for (uint32_t nr= 0; nr < s->sizeKeys() ; nr++)
1421
1768
    {
1422
1769
      if (usable_keys->test(nr))
1423
1770
      {
1444
1791
{
1445
1792
  for (; *ptr ; ptr++)
1446
1793
  {
1447
 
    if ((*ptr)->cmp_offset(getShare()->rec_buff_length))
 
1794
    if ((*ptr)->cmp_offset(s->rec_buff_length))
1448
1795
      return true;
1449
1796
  }
1450
1797
  return false;
1451
1798
}
1452
1799
 
1453
 
/**
1454
 
   True if the table's input and output record buffers are comparable using
1455
 
   compare_records(TABLE*).
1456
 
 */
1457
 
bool Table::records_are_comparable()
1458
 
{
1459
 
  return ((getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) == 0) ||
1460
 
          write_set->is_subset_of(*read_set));
1461
 
}
1462
 
 
1463
 
/**
1464
 
   Compares the input and outbut record buffers of the table to see if a row
1465
 
   has changed. The algorithm iterates over updated columns and if they are
1466
 
   nullable compares NULL bits in the buffer before comparing actual
1467
 
   data. Special care must be taken to compare only the relevant NULL bits and
1468
 
   mask out all others as they may be undefined. The storage engine will not
1469
 
   and should not touch them.
1470
 
 
1471
 
   @param table The table to evaluate.
1472
 
 
1473
 
   @return true if row has changed.
1474
 
   @return false otherwise.
1475
 
*/
1476
 
bool Table::compare_records()
1477
 
{
1478
 
  if (getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) != 0)
1479
 
  {
1480
 
    /*
1481
 
      Storage engine may not have read all columns of the record.  Fields
1482
 
      (including NULL bits) not in the write_set may not have been read and
1483
 
      can therefore not be compared.
1484
 
    */
1485
 
    for (Field **ptr= this->field ; *ptr != NULL; ptr++)
1486
 
    {
1487
 
      Field *f= *ptr;
1488
 
      if (write_set->test(f->position()))
1489
 
      {
1490
 
        if (f->real_maybe_null())
1491
 
        {
1492
 
          unsigned char null_byte_index= f->null_ptr - record[0];
1493
 
 
1494
 
          if (((record[0][null_byte_index]) & f->null_bit) !=
1495
 
              ((record[1][null_byte_index]) & f->null_bit))
1496
 
            return true;
1497
 
        }
1498
 
        if (f->cmp_binary_offset(getShare()->rec_buff_length))
1499
 
          return true;
1500
 
      }
1501
 
    }
1502
 
    return false;
1503
 
  }
1504
 
 
1505
 
  /*
1506
 
    The storage engine has read all columns, so it's safe to compare all bits
1507
 
    including those not in the write_set. This is cheaper than the
1508
 
    field-by-field comparison done above.
1509
 
  */
1510
 
  if (not getShare()->blob_fields + getShare()->hasVariableWidth())
1511
 
    // Fixed-size record: do bitwise comparison of the records
1512
 
    return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) getShare()->getRecordLength());
1513
 
 
 
1800
/* Return false if row hasn't changed */
 
1801
 
 
1802
bool Table::compare_record()
 
1803
{
 
1804
  if (s->blob_fields + s->varchar_fields == 0)
 
1805
    return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) s->getRecordLength());
 
1806
  
1514
1807
  /* Compare null bits */
1515
 
  if (memcmp(null_flags, null_flags + getShare()->rec_buff_length, getShare()->null_bytes))
 
1808
  if (memcmp(null_flags, null_flags + s->rec_buff_length, s->null_bytes))
1516
1809
    return true; /* Diff in NULL value */
1517
1810
 
1518
1811
  /* Compare updated fields */
1519
1812
  for (Field **ptr= field ; *ptr ; ptr++)
1520
1813
  {
1521
 
    if (isWriteSet((*ptr)->position()) &&
1522
 
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
 
1814
    if (isWriteSet((*ptr)->field_index) &&
 
1815
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
1523
1816
      return true;
1524
1817
  }
1525
1818
  return false;
1531
1824
 */
1532
1825
void Table::storeRecord()
1533
1826
{
1534
 
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1827
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) s->getRecordLength());
1535
1828
}
1536
1829
 
1537
1830
/*
1540
1833
 */
1541
1834
void Table::storeRecordAsInsert()
1542
1835
{
1543
 
  assert(insert_values.size() >= getShare()->getRecordLength());
1544
 
  memcpy(&insert_values[0], getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1836
  assert(insert_values.size() >= s->getRecordLength());
 
1837
  memcpy(&insert_values[0], getInsertRecord(), (size_t) s->getRecordLength());
1545
1838
}
1546
1839
 
1547
1840
/*
1550
1843
 */
1551
1844
void Table::storeRecordAsDefault()
1552
1845
{
1553
 
  memcpy(getMutableShare()->getDefaultValues(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1846
  memcpy(s->getDefaultValues(), getInsertRecord(), (size_t) s->getRecordLength());
1554
1847
}
1555
1848
 
1556
1849
/*
1559
1852
 */
1560
1853
void Table::restoreRecord()
1561
1854
{
1562
 
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) getShare()->getRecordLength());
 
1855
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) s->getRecordLength());
1563
1856
}
1564
1857
 
1565
1858
/*
1568
1861
 */
1569
1862
void Table::restoreRecordAsDefault()
1570
1863
{
1571
 
  memcpy(getInsertRecord(), getMutableShare()->getDefaultValues(), (size_t) getShare()->getRecordLength());
 
1864
  memcpy(getInsertRecord(), s->getDefaultValues(), (size_t) s->getRecordLength());
1572
1865
}
1573
1866
 
1574
1867
/*
1578
1871
void Table::emptyRecord()
1579
1872
{
1580
1873
  restoreRecordAsDefault();
1581
 
  memset(null_flags, 255, getShare()->null_bytes);
 
1874
  memset(null_flags, 255, s->null_bytes);
1582
1875
}
1583
1876
 
1584
1877
Table::Table() : 
 
1878
  s(NULL),
1585
1879
  field(NULL),
1586
1880
  cursor(NULL),
1587
1881
  next(NULL),
1590
1884
  write_set(NULL),
1591
1885
  tablenr(0),
1592
1886
  db_stat(0),
1593
 
  def_read_set(),
1594
 
  def_write_set(),
1595
 
  tmp_set(),
1596
1887
  in_use(NULL),
1597
1888
  key_info(NULL),
1598
1889
  next_number_field(NULL),
1600
1891
  timestamp_field(NULL),
1601
1892
  pos_in_table_list(NULL),
1602
1893
  group(NULL),
 
1894
  alias(NULL),
1603
1895
  null_flags(NULL),
1604
1896
  lock_position(0),
1605
1897
  lock_data_start(0),
1626
1918
  quick_condition_rows(0),
1627
1919
  timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
1628
1920
  map(0),
1629
 
  quick_rows(),
1630
 
  const_key_parts(),
1631
 
  quick_key_parts(),
1632
 
  quick_n_ranges()
 
1921
  is_placeholder_created(0)
1633
1922
{
 
1923
  memset(&def_read_set, 0, sizeof(MyBitmap)); /**< Default read set of columns */
 
1924
  memset(&def_write_set, 0, sizeof(MyBitmap)); /**< Default write set of columns */
 
1925
  memset(&tmp_set, 0, sizeof(MyBitmap)); /* Not sure about this... */
 
1926
 
1634
1927
  record[0]= (unsigned char *) 0;
1635
1928
  record[1]= (unsigned char *) 0;
 
1929
 
 
1930
  reginfo.reset();
 
1931
  covering_keys.reset();
 
1932
  quick_keys.reset();
 
1933
  merge_keys.reset();
 
1934
 
 
1935
  keys_in_use_for_query.reset();
 
1936
  keys_in_use_for_group_by.reset();
 
1937
  keys_in_use_for_order_by.reset();
 
1938
 
 
1939
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
 
1940
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
 
1941
 
 
1942
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
 
1943
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
1636
1944
}
1637
1945
 
1638
1946
/*****************************************************************************
1654
1962
    print them to the .err log
1655
1963
  */
1656
1964
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
1657
 
    errmsg_printf(error::ERROR, _("Got error %d when reading table '%s'"),
1658
 
                  error, getShare()->getPath());
 
1965
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
 
1966
                  error, s->getPath());
1659
1967
  print_error(error, MYF(0));
1660
1968
 
1661
1969
  return 1;
1678
1986
  tablenr= table_number;
1679
1987
  map= (table_map) 1 << table_number;
1680
1988
  force_index= table_list->force_index;
1681
 
  covering_keys= getShare()->keys_for_keyread;
 
1989
  covering_keys= s->keys_for_keyread;
1682
1990
  merge_keys.reset();
1683
1991
}
1684
1992
 
1698
2006
  return false;
1699
2007
}
1700
2008
 
1701
 
 
1702
 
void Table::filesort_free_buffers(bool full)
1703
 
{
1704
 
  if (sort.record_pointers)
1705
 
  {
1706
 
    free((unsigned char*) sort.record_pointers);
1707
 
    sort.record_pointers=0;
1708
 
  }
1709
 
  if (full)
1710
 
  {
1711
 
    if (sort.sort_keys )
1712
 
    {
1713
 
      if ((unsigned char*) sort.sort_keys)
1714
 
        free((unsigned char*) sort.sort_keys);
1715
 
      sort.sort_keys= 0;
1716
 
    }
1717
 
    if (sort.buffpek)
1718
 
    {
1719
 
      if ((unsigned char*) sort.buffpek)
1720
 
        free((unsigned char*) sort.buffpek);
1721
 
      sort.buffpek= 0;
1722
 
      sort.buffpek_len= 0;
1723
 
    }
1724
 
  }
1725
 
 
1726
 
  if (sort.addon_buf)
1727
 
  {
1728
 
    free((char *) sort.addon_buf);
1729
 
    free((char *) sort.addon_field);
1730
 
    sort.addon_buf=0;
1731
 
    sort.addon_field=0;
1732
 
  }
1733
 
}
1734
 
 
1735
 
/*
1736
 
  Is this instance of the table should be reopen or represents a name-lock?
1737
 
*/
1738
 
bool Table::needs_reopen_or_name_lock() const
1739
 
1740
 
  return getShare()->getVersion() != refresh_version;
1741
 
}
1742
 
 
1743
 
uint32_t Table::index_flags(uint32_t idx) const
1744
 
{
1745
 
  return getShare()->getEngine()->index_flags(getShare()->getKeyInfo(idx).algorithm);
1746
 
}
1747
 
 
1748
 
void Table::print_error(int error, myf errflag) const
1749
 
{
1750
 
  getShare()->getEngine()->print_error(error, errflag, *this);
1751
 
}
1752
 
 
1753
2009
} /* namespace drizzled */