~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Monty Taylor
  • Date: 2010-10-09 21:00:09 UTC
  • mto: This revision was merged to the branch mainline in revision 1833.
  • Revision ID: mordred@inaugust.com-20101009210009-ri97ge7nno005ox2
Updated pandora-build files to version 0.159

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
/* Some general useful functions */
18
18
 
19
 
#include <config.h>
 
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
                             O_RDWR,
 
1569
                             HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
 
1570
  {
 
1571
    print_error(error, MYF(0));
 
1572
    db_stat= 0;
 
1573
    return true;
 
1574
  }
 
1575
  (void) cursor->extra(HA_EXTRA_QUICK);         /* Faster */
 
1576
  return false;
 
1577
}
 
1578
 
 
1579
 
 
1580
/*
 
1581
  Create MyISAM temporary table
 
1582
 
 
1583
  SYNOPSIS
 
1584
    create_myisam_tmp_table()
 
1585
      keyinfo         Description of the index (there is always one index)
 
1586
      start_recinfo   MyISAM's column descriptions
 
1587
      recinfo INOUT   End of MyISAM's column descriptions
 
1588
      options         Option bits
 
1589
 
 
1590
  DESCRIPTION
 
1591
    Create a MyISAM temporary table according to passed description. The is
 
1592
    assumed to have one unique index or constraint.
 
1593
 
 
1594
    The passed array or MI_COLUMNDEF structures must have this form:
 
1595
 
 
1596
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
 
1597
         when there are many nullable columns)
 
1598
      2. Table columns
 
1599
      3. One free MI_COLUMNDEF element (*recinfo points here)
 
1600
 
 
1601
    This function may use the free element to create hash column for unique
 
1602
    constraint.
 
1603
 
 
1604
   RETURN
 
1605
     false - OK
 
1606
     true  - Error
 
1607
*/
 
1608
 
 
1609
bool Table::create_myisam_tmp_table(KeyInfo *keyinfo,
 
1610
                                    MI_COLUMNDEF *start_recinfo,
 
1611
                                    MI_COLUMNDEF **recinfo,
 
1612
                                    uint64_t options)
 
1613
{
 
1614
  int error;
 
1615
  MI_KEYDEF keydef;
 
1616
  MI_UNIQUEDEF uniquedef;
 
1617
  TableShare *share= s;
 
1618
 
 
1619
  if (share->sizeKeys())
 
1620
  {                                             // Get keys for ni_create
 
1621
    bool using_unique_constraint= false;
 
1622
    HA_KEYSEG *seg= (HA_KEYSEG*) this->mem_root.alloc_root(sizeof(*seg) * keyinfo->key_parts);
 
1623
    if (not seg)
 
1624
      return true;
 
1625
 
 
1626
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
 
1627
    if (keyinfo->key_length >= cursor->getEngine()->max_key_length() ||
 
1628
        keyinfo->key_parts > cursor->getEngine()->max_key_parts() ||
 
1629
        share->uniques)
 
1630
    {
 
1631
      /* Can't create a key; Make a unique constraint instead of a key */
 
1632
      share->keys=    0;
 
1633
      share->uniques= 1;
 
1634
      using_unique_constraint= true;
 
1635
      memset(&uniquedef, 0, sizeof(uniquedef));
 
1636
      uniquedef.keysegs=keyinfo->key_parts;
 
1637
      uniquedef.seg=seg;
 
1638
      uniquedef.null_are_equal=1;
 
1639
 
 
1640
      /* Create extra column for hash value */
 
1641
      memset(*recinfo, 0, sizeof(**recinfo));
 
1642
      (*recinfo)->type= FIELD_CHECK;
 
1643
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
 
1644
      (*recinfo)++;
 
1645
      share->setRecordLength(share->getRecordLength() + MI_UNIQUE_HASH_LENGTH);
 
1646
    }
 
1647
    else
 
1648
    {
 
1649
      /* Create an unique key */
 
1650
      memset(&keydef, 0, sizeof(keydef));
 
1651
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
 
1652
      keydef.keysegs=  keyinfo->key_parts;
 
1653
      keydef.seg= seg;
 
1654
    }
 
1655
    for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
 
1656
    {
 
1657
      Field *key_field=keyinfo->key_part[i].field;
 
1658
      seg->flag=     0;
 
1659
      seg->language= key_field->charset()->number;
 
1660
      seg->length=   keyinfo->key_part[i].length;
 
1661
      seg->start=    keyinfo->key_part[i].offset;
 
1662
      if (key_field->flags & BLOB_FLAG)
 
1663
      {
 
1664
        seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
 
1665
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
 
1666
        seg->bit_start= (uint8_t)(key_field->pack_length()
 
1667
                                  - share->blob_ptr_size);
 
1668
        seg->flag= HA_BLOB_PART;
 
1669
        seg->length= 0;                 // Whole blob in unique constraint
 
1670
      }
 
1671
      else
 
1672
      {
 
1673
        seg->type= keyinfo->key_part[i].type;
 
1674
      }
 
1675
      if (!(key_field->flags & NOT_NULL_FLAG))
 
1676
      {
 
1677
        seg->null_bit= key_field->null_bit;
 
1678
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) getInsertRecord());
 
1679
        /*
 
1680
          We are using a GROUP BY on something that contains NULL
 
1681
          In this case we have to tell MyISAM that two NULL should
 
1682
          on INSERT be regarded at the same value
 
1683
        */
 
1684
        if (! using_unique_constraint)
 
1685
          keydef.flag|= HA_NULL_ARE_EQUAL;
 
1686
      }
 
1687
    }
 
1688
  }
 
1689
  MI_CREATE_INFO create_info;
 
1690
 
 
1691
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
1692
      OPTION_BIG_TABLES)
 
1693
    create_info.data_file_length= ~(uint64_t) 0;
 
1694
 
 
1695
  if ((error= mi_create(share->getTableName(), share->sizeKeys(), &keydef,
 
1696
                        (uint32_t) (*recinfo-start_recinfo),
 
1697
                        start_recinfo,
 
1698
                        share->uniques, &uniquedef,
 
1699
                        &create_info,
 
1700
                        HA_CREATE_TMP_TABLE)))
 
1701
  {
 
1702
    print_error(error, MYF(0));
 
1703
    db_stat= 0;
 
1704
 
 
1705
    return true;
 
1706
  }
 
1707
  in_use->status_var.created_tmp_disk_tables++;
 
1708
  share->db_record_offset= 1;
 
1709
  return false;
 
1710
}
 
1711
 
 
1712
 
 
1713
void Table::free_tmp_table(Session *session)
 
1714
{
 
1715
  memory::Root own_root= mem_root;
 
1716
  const char *save_proc_info;
 
1717
 
 
1718
  save_proc_info= session->get_proc_info();
 
1719
  session->set_proc_info("removing tmp table");
 
1720
 
 
1721
  // Release latches since this can take a long time
 
1722
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
1723
 
 
1724
  if (cursor)
 
1725
  {
 
1726
    if (db_stat)
 
1727
    {
 
1728
      cursor->closeMarkForDelete(s->getTableName());
 
1729
    }
 
1730
 
 
1731
    TableIdentifier identifier(s->getSchemaName(), s->getTableName(), s->getTableName());
 
1732
    s->db_type()->doDropTable(*session, identifier);
 
1733
 
 
1734
    delete cursor;
 
1735
  }
 
1736
 
 
1737
  /* free blobs */
 
1738
  for (Field **ptr= field ; *ptr ; ptr++)
 
1739
  {
 
1740
    (*ptr)->free();
 
1741
  }
 
1742
  free_io_cache();
 
1743
 
 
1744
  own_root.free_root(MYF(0)); /* the table is allocated in its own root */
 
1745
  session->set_proc_info(save_proc_info);
 
1746
}
 
1747
 
 
1748
my_bitmap_map *Table::use_all_columns(MyBitmap *bitmap)
 
1749
{
 
1750
  my_bitmap_map *old= bitmap->getBitmap();
 
1751
  bitmap->setBitmap(s->all_set.getBitmap());
1396
1752
  return old;
1397
1753
}
1398
1754
 
1399
 
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
 
1755
void Table::restore_column_map(my_bitmap_map *old)
1400
1756
{
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
 
  }
 
1757
  read_set->setBitmap(old);
1412
1758
}
1413
1759
 
1414
1760
uint32_t Table::find_shortest_key(const key_map *usable_keys)
1417
1763
  uint32_t best= MAX_KEY;
1418
1764
  if (usable_keys->any())
1419
1765
  {
1420
 
    for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
 
1766
    for (uint32_t nr= 0; nr < s->sizeKeys() ; nr++)
1421
1767
    {
1422
1768
      if (usable_keys->test(nr))
1423
1769
      {
1444
1790
{
1445
1791
  for (; *ptr ; ptr++)
1446
1792
  {
1447
 
    if ((*ptr)->cmp_offset(getShare()->rec_buff_length))
 
1793
    if ((*ptr)->cmp_offset(s->rec_buff_length))
1448
1794
      return true;
1449
1795
  }
1450
1796
  return false;
1451
1797
}
1452
1798
 
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
 
 
 
1799
/* Return false if row hasn't changed */
 
1800
 
 
1801
bool Table::compare_record()
 
1802
{
 
1803
  if (s->blob_fields + s->varchar_fields == 0)
 
1804
    return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) s->getRecordLength());
 
1805
  
1514
1806
  /* Compare null bits */
1515
 
  if (memcmp(null_flags, null_flags + getShare()->rec_buff_length, getShare()->null_bytes))
 
1807
  if (memcmp(null_flags, null_flags + s->rec_buff_length, s->null_bytes))
1516
1808
    return true; /* Diff in NULL value */
1517
1809
 
1518
1810
  /* Compare updated fields */
1519
1811
  for (Field **ptr= field ; *ptr ; ptr++)
1520
1812
  {
1521
 
    if (isWriteSet((*ptr)->position()) &&
1522
 
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
 
1813
    if (isWriteSet((*ptr)->field_index) &&
 
1814
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
1523
1815
      return true;
1524
1816
  }
1525
1817
  return false;
1531
1823
 */
1532
1824
void Table::storeRecord()
1533
1825
{
1534
 
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1826
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) s->getRecordLength());
1535
1827
}
1536
1828
 
1537
1829
/*
1540
1832
 */
1541
1833
void Table::storeRecordAsInsert()
1542
1834
{
1543
 
  assert(insert_values.size() >= getShare()->getRecordLength());
1544
 
  memcpy(&insert_values[0], getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1835
  assert(insert_values.size() >= s->getRecordLength());
 
1836
  memcpy(&insert_values[0], getInsertRecord(), (size_t) s->getRecordLength());
1545
1837
}
1546
1838
 
1547
1839
/*
1550
1842
 */
1551
1843
void Table::storeRecordAsDefault()
1552
1844
{
1553
 
  memcpy(getMutableShare()->getDefaultValues(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1845
  memcpy(s->getDefaultValues(), getInsertRecord(), (size_t) s->getRecordLength());
1554
1846
}
1555
1847
 
1556
1848
/*
1559
1851
 */
1560
1852
void Table::restoreRecord()
1561
1853
{
1562
 
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) getShare()->getRecordLength());
 
1854
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) s->getRecordLength());
1563
1855
}
1564
1856
 
1565
1857
/*
1568
1860
 */
1569
1861
void Table::restoreRecordAsDefault()
1570
1862
{
1571
 
  memcpy(getInsertRecord(), getMutableShare()->getDefaultValues(), (size_t) getShare()->getRecordLength());
 
1863
  memcpy(getInsertRecord(), s->getDefaultValues(), (size_t) s->getRecordLength());
1572
1864
}
1573
1865
 
1574
1866
/*
1578
1870
void Table::emptyRecord()
1579
1871
{
1580
1872
  restoreRecordAsDefault();
1581
 
  memset(null_flags, 255, getShare()->null_bytes);
 
1873
  memset(null_flags, 255, s->null_bytes);
1582
1874
}
1583
1875
 
1584
1876
Table::Table() : 
 
1877
  s(NULL),
1585
1878
  field(NULL),
1586
1879
  cursor(NULL),
1587
1880
  next(NULL),
1590
1883
  write_set(NULL),
1591
1884
  tablenr(0),
1592
1885
  db_stat(0),
1593
 
  def_read_set(),
1594
 
  def_write_set(),
1595
 
  tmp_set(),
1596
1886
  in_use(NULL),
1597
1887
  key_info(NULL),
1598
1888
  next_number_field(NULL),
1600
1890
  timestamp_field(NULL),
1601
1891
  pos_in_table_list(NULL),
1602
1892
  group(NULL),
 
1893
  alias(NULL),
1603
1894
  null_flags(NULL),
1604
1895
  lock_position(0),
1605
1896
  lock_data_start(0),
1626
1917
  quick_condition_rows(0),
1627
1918
  timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
1628
1919
  map(0),
1629
 
  quick_rows(),
1630
 
  const_key_parts(),
1631
 
  quick_key_parts(),
1632
 
  quick_n_ranges()
 
1920
  is_placeholder_created(0)
1633
1921
{
 
1922
  memset(&def_read_set, 0, sizeof(MyBitmap)); /**< Default read set of columns */
 
1923
  memset(&def_write_set, 0, sizeof(MyBitmap)); /**< Default write set of columns */
 
1924
  memset(&tmp_set, 0, sizeof(MyBitmap)); /* Not sure about this... */
 
1925
 
1634
1926
  record[0]= (unsigned char *) 0;
1635
1927
  record[1]= (unsigned char *) 0;
 
1928
 
 
1929
  reginfo.reset();
 
1930
  covering_keys.reset();
 
1931
  quick_keys.reset();
 
1932
  merge_keys.reset();
 
1933
 
 
1934
  keys_in_use_for_query.reset();
 
1935
  keys_in_use_for_group_by.reset();
 
1936
  keys_in_use_for_order_by.reset();
 
1937
 
 
1938
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
 
1939
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
 
1940
 
 
1941
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
 
1942
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
1636
1943
}
1637
1944
 
1638
1945
/*****************************************************************************
1654
1961
    print them to the .err log
1655
1962
  */
1656
1963
  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());
 
1964
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
 
1965
                  error, s->getPath());
1659
1966
  print_error(error, MYF(0));
1660
1967
 
1661
1968
  return 1;
1678
1985
  tablenr= table_number;
1679
1986
  map= (table_map) 1 << table_number;
1680
1987
  force_index= table_list->force_index;
1681
 
  covering_keys= getShare()->keys_for_keyread;
 
1988
  covering_keys= s->keys_for_keyread;
1682
1989
  merge_keys.reset();
1683
1990
}
1684
1991
 
1698
2005
  return false;
1699
2006
}
1700
2007
 
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
2008
} /* namespace drizzled */