~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Monty Taylor
  • Date: 2010-08-03 18:21:58 UTC
  • mto: (1680.2.6 build)
  • mto: This revision was merged to the branch mainline in revision 1683.
  • Revision ID: mordred@inaugust.com-20100803182158-nkmgnlohodud4290
Made existence of intltool and gettext optional.

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;
191
196
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
192
197
 
193
198
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
199
  memset(&sort, 0, sizeof(filesort_info_st));
194
200
}
195
201
 
196
202
 
197
203
 
198
204
/* Deallocate temporary blob storage */
199
205
 
200
 
void free_blobs(Table *table)
 
206
void free_blobs(register Table *table)
201
207
{
202
208
  uint32_t *ptr, *end;
203
209
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
223
229
    
224
230
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
225
231
 
226
 
  List<String>::iterator it(strings.begin());
 
232
  List_iterator<String> it(strings);
227
233
  String *tmp;
228
234
  for (uint32_t i= 0; (tmp= it++); i++)
229
235
  {
239
245
 
240
246
        /* Check that the integer is in the internal */
241
247
 
242
 
int set_zone(int nr, int min_zone, int max_zone)
 
248
int set_zone(register int nr, int min_zone, int max_zone)
243
249
{
244
250
  if (nr<=min_zone)
245
251
    return (min_zone);
248
254
  return (nr);
249
255
} /* set_zone */
250
256
 
 
257
        /* Adjust number to next larger disk buffer */
 
258
 
 
259
ulong next_io_size(register ulong pos)
 
260
{
 
261
  register ulong offset;
 
262
  if ((offset= pos & (IO_SIZE-1)))
 
263
    return pos-offset+IO_SIZE;
 
264
  return pos;
 
265
} /* next_io_size */
 
266
 
251
267
 
252
268
/*
253
269
  Store an SQL quoted string.
275
291
        (mblen= my_ismbchar(default_charset_info, pos, end)))
276
292
    {
277
293
      res->append(pos, mblen);
278
 
      pos+= mblen - 1;
 
294
      pos+= mblen;
279
295
      if (pos >= end)
280
296
        break;
281
297
      continue;
311
327
}
312
328
 
313
329
 
 
330
/*
 
331
  Set up column usage bitmaps for a temporary table
 
332
 
 
333
  IMPLEMENTATION
 
334
    For temporary tables, we need one bitmap with all columns set and
 
335
    a tmp_set bitmap to be used by things like filesort.
 
336
*/
 
337
 
 
338
void Table::setup_tmp_table_column_bitmaps(unsigned char *bitmaps)
 
339
{
 
340
  uint32_t field_count= s->sizeFields();
 
341
 
 
342
  this->def_read_set.init((my_bitmap_map*) bitmaps, field_count);
 
343
  this->tmp_set.init((my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count);
 
344
 
 
345
  /* write_set and all_set are copies of read_set */
 
346
  def_write_set= def_read_set;
 
347
  s->all_set= def_read_set;
 
348
  this->getMutableShare()->all_set.setAll();
 
349
  default_column_bitmaps();
 
350
}
 
351
 
 
352
 
314
353
int rename_file_ext(const char * from,const char * to,const char * ext)
315
354
{
316
355
  string from_s, to_s;
323
362
}
324
363
 
325
364
/*
 
365
  Check if database name is valid
 
366
 
 
367
  SYNPOSIS
 
368
    check_db_name()
 
369
    org_name            Name of database and length
 
370
 
 
371
  RETURN
 
372
    false error
 
373
    true ok
 
374
*/
 
375
 
 
376
bool check_db_name(Session *session, SchemaIdentifier &schema_identifier)
 
377
{
 
378
  if (not plugin::Authorization::isAuthorized(session->getSecurityContext(), schema_identifier))
 
379
  {
 
380
    return false;
 
381
  }
 
382
 
 
383
  return schema_identifier.isValid();
 
384
}
 
385
 
 
386
/*
326
387
  Allow anything as a table name, as long as it doesn't contain an
327
388
  ' ' at the end
328
389
  returns 1 on error
392
453
    bitmap_clear_all(&table->def_read_set);
393
454
    bitmap_clear_all(&table->def_write_set);
394
455
  */
395
 
  def_read_set.reset();
396
 
  def_write_set.reset();
397
 
  column_bitmaps_set(def_read_set, def_write_set);
 
456
  def_read_set.clearAll();
 
457
  def_write_set.clearAll();
 
458
  column_bitmaps_set(&def_read_set, &def_write_set);
398
459
}
399
460
 
400
461
 
411
472
{
412
473
 
413
474
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
414
 
      getShare()->hasPrimaryKey())
 
475
      s->hasPrimaryKey())
415
476
  {
416
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
477
    mark_columns_used_by_index_no_reset(s->getPrimaryKey());
417
478
  }
418
479
  return;
419
480
}
431
492
 
432
493
void Table::mark_columns_used_by_index(uint32_t index)
433
494
{
434
 
  boost::dynamic_bitset<> *bitmap= &tmp_set;
 
495
  MyBitmap *bitmap= &tmp_set;
435
496
 
436
497
  (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);
 
498
  bitmap->clearAll();
 
499
  mark_columns_used_by_index_no_reset(index, bitmap);
 
500
  column_bitmaps_set(bitmap, bitmap);
440
501
  return;
441
502
}
442
503
 
468
529
 
469
530
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
470
531
{
471
 
    mark_columns_used_by_index_no_reset(index, *read_set);
 
532
    mark_columns_used_by_index_no_reset(index, read_set);
472
533
}
473
534
 
474
 
 
475
535
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
476
 
                                                boost::dynamic_bitset<>& bitmap)
 
536
                                                MyBitmap *bitmap)
477
537
{
478
538
  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
 
  }
 
539
  KeyPartInfo *key_part_end= (key_part +
 
540
                                key_info[index].key_parts);
 
541
  for (;key_part != key_part_end; key_part++)
 
542
    bitmap->setBit(key_part->fieldnr-1);
485
543
}
486
544
 
487
545
 
500
558
    We must set bit in read set as update_auto_increment() is using the
501
559
    store() to check overflow of auto_increment values
502
560
  */
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);
 
561
  setReadSet(found_next_number_field->field_index);
 
562
  setWriteSet(found_next_number_field->field_index);
 
563
  if (s->next_number_keypart)
 
564
    mark_columns_used_by_index_no_reset(s->next_number_index);
507
565
}
508
566
 
509
567
 
534
592
    be able to do an delete
535
593
 
536
594
  */
537
 
  if (not getShare()->hasPrimaryKey())
 
595
  if (not s->hasPrimaryKey())
538
596
  {
539
597
    /* fallback to use all columns in the table to identify row */
540
598
    use_all_columns();
541
599
    return;
542
600
  }
543
601
  else
544
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
602
    mark_columns_used_by_index_no_reset(s->getPrimaryKey());
545
603
 
546
604
  /* If we the engine wants all predicates we mark all keys */
547
605
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
550
608
    for (reg_field= field ; *reg_field ; reg_field++)
551
609
    {
552
610
      if ((*reg_field)->flags & PART_KEY_FLAG)
553
 
        setReadSet((*reg_field)->position());
 
611
        setReadSet((*reg_field)->field_index);
554
612
    }
555
613
  }
556
614
}
582
640
    the primary key, the hidden primary key or all columns to be
583
641
    able to do an update
584
642
  */
585
 
  if (not getShare()->hasPrimaryKey())
 
643
  if (not s->hasPrimaryKey())
586
644
  {
587
645
    /* fallback to use all columns in the table to identify row */
588
646
    use_all_columns();
589
647
    return;
590
648
  }
591
649
  else
592
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
650
    mark_columns_used_by_index_no_reset(s->getPrimaryKey());
593
651
 
594
652
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
595
653
  {
599
657
    {
600
658
      /* Merge keys is all keys that had a column refered to in the query */
601
659
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
602
 
        setReadSet((*reg_field)->position());
 
660
        setReadSet((*reg_field)->field_index);
603
661
    }
604
662
  }
605
663
 
637
695
  return length;
638
696
}
639
697
 
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
698
/****************************************************************************
653
699
 Functions for creating temporary tables.
654
700
****************************************************************************/
686
732
  */
687
733
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
688
734
      (org_field->flags & BLOB_FLAG))
689
 
  {
690
 
    table->setVariableWidth();
691
735
    new_field= new Field_varstring(convert_blob_length,
692
736
                                   org_field->maybe_null(),
693
 
                                   org_field->field_name,
 
737
                                   org_field->field_name, table->getMutableShare(),
694
738
                                   org_field->charset());
695
 
  }
696
739
  else
697
 
  {
698
740
    new_field= org_field->new_field(session->mem_root, table,
699
741
                                    table == org_field->getTable());
700
 
  }
701
742
  if (new_field)
702
743
  {
703
744
    new_field->init(table);
750
791
 
751
792
Table *
752
793
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
753
 
                 Order *group, bool distinct, bool save_sum_fields,
 
794
                 order_st *group, bool distinct, bool save_sum_fields,
754
795
                 uint64_t select_options, ha_rows rows_limit,
755
796
                 const char *table_alias)
756
797
{
757
798
  memory::Root *mem_root_save;
 
799
  Table *table;
758
800
  uint  i,field_count,null_count,null_pack_length;
759
801
  uint32_t  copy_func_count= param->func_count;
760
802
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
764
806
  bool  using_unique_constraint= false;
765
807
  bool  use_packed_rows= true;
766
808
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
767
 
  unsigned char *pos, *group_buff;
 
809
  unsigned char *pos, *group_buff, *bitmaps;
768
810
  unsigned char *null_flags;
769
811
  Field **reg_field, **from_field, **default_field;
770
812
  CopyField *copy= 0;
776
818
  bool force_copy_fields= param->force_copy_fields;
777
819
  uint64_t max_rows= 0;
778
820
 
779
 
  session->status_var.created_tmp_tables++;
 
821
  status_var_increment(session->status_var.created_tmp_tables);
780
822
 
781
823
  if (group)
782
824
  {
784
826
    {
785
827
      group= 0;                                 // Can't use group key
786
828
    }
787
 
    else for (Order *tmp=group ; tmp ; tmp=tmp->next)
 
829
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
788
830
    {
789
831
      /*
790
832
        marker == 4 means two things:
817
859
    copy_func_count+= param->sum_func_count;
818
860
  }
819
861
 
820
 
  table::Singular *table;
821
 
  table= session->getInstanceTable(); // This will not go into the tableshare cache, so no key is used.
 
862
  TableShareInstance *share= session->getTemporaryShare(message::Table::INTERNAL); // This will not go into the tableshare cache, so no key is used.
822
863
 
823
 
  if (not table->getMemRoot()->multi_alloc_root(0,
 
864
  if (not share->getMemRoot()->multi_alloc_root(0,
824
865
                                                &default_field, sizeof(Field*) * (field_count),
825
866
                                                &from_field, sizeof(Field*)*field_count,
826
867
                                                &copy_func, sizeof(*copy_func)*(copy_func_count+1),
829
870
                                                &param->start_recinfo, sizeof(*param->recinfo)*(field_count*2+4),
830
871
                                                &group_buff, (group && ! using_unique_constraint ?
831
872
                                                              param->group_length : 0),
 
873
                                                &bitmaps, bitmap_buffer_size(field_count)*2,
832
874
                                                NULL))
833
875
  {
834
876
    return NULL;
841
883
  param->items_to_copy= copy_func;
842
884
  /* make table according to fields */
843
885
 
 
886
  table= share->getTable();
 
887
 
844
888
  memset(default_field, 0, sizeof(Field*) * (field_count));
845
889
  memset(from_field, 0, sizeof(Field*)*field_count);
846
890
 
847
891
  mem_root_save= session->mem_root;
848
892
  session->mem_root= table->getMemRoot();
849
893
 
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);
 
894
  share->setFields(field_count+1);
 
895
  table->setFields(share->getFields(true));
 
896
  reg_field= share->getFields(true);
 
897
  table->alias= table_alias;
854
898
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
855
899
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
856
900
  table->map=1;
861
905
  table->covering_keys.reset();
862
906
  table->keys_in_use_for_query.reset();
863
907
 
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();
 
908
  table->setShare(share);
 
909
  share->blob_field.resize(field_count+1);
 
910
  uint32_t *blob_field= &share->blob_field[0];
 
911
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
912
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
 
913
  share->table_charset= param->table_charset;
 
914
  share->keys_for_keyread.reset();
 
915
  share->keys_in_use.reset();
870
916
 
871
917
  /* Calculate which type of fields we will store in the temporary table */
872
918
 
874
920
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
875
921
  param->using_indirect_summary_function= 0;
876
922
 
877
 
  List<Item>::iterator li(fields.begin());
 
923
  List_iterator_fast<Item> li(fields);
878
924
  Item *item;
879
925
  Field **tmp_from_field=from_field;
880
926
  while ((item=li++))
943
989
            */
944
990
            (*argp)->maybe_null=1;
945
991
          }
946
 
          new_field->setPosition(fieldnr++);
 
992
          new_field->field_index= fieldnr++;
947
993
        }
948
994
      }
949
995
    }
990
1036
        group_null_items++;
991
1037
        new_field->flags|= GROUP_FLAG;
992
1038
      }
993
 
      new_field->setPosition(fieldnr++);
 
1039
      new_field->field_index= fieldnr++;
994
1040
      *(reg_field++)= new_field;
995
1041
    }
996
1042
    if (!--hidden_field_count)
1013
1059
  field_count= fieldnr;
1014
1060
  *reg_field= 0;
1015
1061
  *blob_field= 0;                               // End marker
1016
 
  table->getMutableShare()->setFieldSize(field_count);
 
1062
  share->fields= field_count;
1017
1063
 
1018
1064
  /* If result table is small; use a heap */
1019
1065
  /* future: storage engine selection can be made dynamic? */
1020
1066
  if (blob_count || using_unique_constraint || 
1021
 
      (session->getLex()->select_lex.options & SELECT_BIG_RESULT) ||
1022
 
      (session->getLex()->current_select->olap == ROLLUP_TYPE) ||
 
1067
      (session->lex->select_lex.options & SELECT_BIG_RESULT) ||
 
1068
      (session->lex->current_select->olap == ROLLUP_TYPE) ||
1023
1069
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
1024
1070
  {
1025
 
    table->getMutableShare()->storage_engine= myisam_engine;
1026
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
1071
    share->storage_engine= myisam_engine;
 
1072
    table->cursor= share->db_type()->getCursor(*share, table->getMemRoot());
1027
1073
    if (group &&
1028
1074
        (param->group_parts > table->cursor->getEngine()->max_key_parts() ||
1029
1075
         param->group_length > table->cursor->getEngine()->max_key_length()))
1033
1079
  }
1034
1080
  else
1035
1081
  {
1036
 
    table->getMutableShare()->storage_engine= heap_engine;
1037
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
1082
    share->storage_engine= heap_engine;
 
1083
    table->cursor= share->db_type()->getCursor(*share, table->getMemRoot());
1038
1084
  }
1039
1085
  if (! table->cursor)
1040
1086
    goto err;
1043
1089
  if (! using_unique_constraint)
1044
1090
    reclength+= group_null_items;       // null flag is stored separately
1045
1091
 
1046
 
  table->getMutableShare()->blob_fields= blob_count;
 
1092
  share->blob_fields= blob_count;
1047
1093
  if (blob_count == 0)
1048
1094
  {
1049
1095
    /* We need to ensure that first byte is not 0 for the delete link */
1062
1108
  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
1109
    use_packed_rows= 1;
1064
1110
 
1065
 
  table->getMutableShare()->setRecordLength(reclength);
 
1111
  share->setRecordLength(reclength);
1066
1112
  {
1067
1113
    uint32_t alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
1068
 
    table->getMutableShare()->rec_buff_length= alloc_length;
 
1114
    share->rec_buff_length= alloc_length;
1069
1115
    if (!(table->record[0]= (unsigned char*) table->alloc_root(alloc_length*2)))
1070
1116
    {
1071
1117
      goto err;
1072
1118
    }
1073
1119
    table->record[1]= table->getInsertRecord()+alloc_length;
1074
 
    table->getMutableShare()->resizeDefaultValues(alloc_length);
 
1120
    share->resizeDefaultValues(alloc_length);
1075
1121
  }
1076
1122
  copy_func[0]= 0;                              // End marker
1077
1123
  param->func_count= copy_func - param->items_to_copy;
1078
1124
 
1079
 
  table->setup_tmp_table_column_bitmaps();
 
1125
  table->setup_tmp_table_column_bitmaps(bitmaps);
1080
1126
 
1081
1127
  recinfo=param->start_recinfo;
1082
1128
  null_flags=(unsigned char*) table->getInsertRecord();
1090
1136
    memset(null_flags, 255, null_pack_length);  // Set null fields
1091
1137
 
1092
1138
    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;
 
1139
    share->null_fields= null_count+ hidden_null_count;
 
1140
    share->null_bytes= null_pack_length;
1095
1141
  }
1096
1142
  null_count= (blob_count == 0) ? 1 : 0;
1097
1143
  hidden_field_count=param->hidden_field_count;
1182
1228
  }
1183
1229
  else
1184
1230
  {
1185
 
    max_rows= (uint64_t) (((table->getMutableShare()->db_type() == heap_engine) ?
 
1231
    max_rows= (uint64_t) (((share->db_type() == heap_engine) ?
1186
1232
                           min(session->variables.tmp_table_size,
1187
1233
                               session->variables.max_heap_table_size) :
1188
1234
                           session->variables.tmp_table_size) /
1189
 
                          table->getMutableShare()->getRecordLength());
 
1235
                          share->getRecordLength());
1190
1236
  }
1191
1237
 
1192
1238
  set_if_bigger(max_rows, (uint64_t)1); // For dummy start options
1196
1242
  */
1197
1243
  set_if_smaller(max_rows, rows_limit);
1198
1244
 
1199
 
  table->getMutableShare()->setMaxRows(max_rows);
 
1245
  share->setMaxRows(max_rows);
1200
1246
 
1201
1247
  param->end_write_records= rows_limit;
1202
1248
 
1206
1252
  {
1207
1253
    table->group=group;                         /* Table is grouped by key */
1208
1254
    param->group_buff=group_buff;
1209
 
    table->getMutableShare()->keys=1;
1210
 
    table->getMutableShare()->uniques= test(using_unique_constraint);
 
1255
    share->keys=1;
 
1256
    share->uniques= test(using_unique_constraint);
1211
1257
    table->key_info=keyinfo;
1212
1258
    keyinfo->key_part=key_part_info;
1213
1259
    keyinfo->flags=HA_NOSAME;
1216
1262
    keyinfo->rec_per_key= 0;
1217
1263
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1218
1264
    keyinfo->name= (char*) "group_key";
1219
 
    Order *cur_group= group;
 
1265
    order_st *cur_group= group;
1220
1266
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
1221
1267
    {
1222
1268
      Field *field=(*cur_group->item)->get_tmp_table_field();
1278
1324
        indexes on blobs with arbitrary length. Such indexes cannot be
1279
1325
        used for lookups.
1280
1326
      */
1281
 
      table->getMutableShare()->uniques= 1;
 
1327
      share->uniques= 1;
1282
1328
    }
1283
1329
    null_pack_length-=hidden_null_pack_length;
1284
1330
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
1285
 
                         (table->getMutableShare()->uniques ? test(null_pack_length) : 0));
 
1331
                         (share->uniques ? test(null_pack_length) : 0));
1286
1332
    table->distinct= 1;
1287
 
    table->getMutableShare()->keys= 1;
 
1333
    share->keys= 1;
1288
1334
    if (!(key_part_info= (KeyPartInfo*)
1289
1335
         table->alloc_root(keyinfo->key_parts * sizeof(KeyPartInfo))))
1290
1336
      goto err;
1302
1348
      blobs can distinguish NULL from 0. This extra field is not needed
1303
1349
      when we do not use UNIQUE indexes for blobs.
1304
1350
    */
1305
 
    if (null_pack_length && table->getMutableShare()->uniques)
 
1351
    if (null_pack_length && share->uniques)
1306
1352
    {
1307
1353
      key_part_info->null_bit= 0;
1308
1354
      key_part_info->offset=hidden_null_pack_length;
1309
1355
      key_part_info->length=null_pack_length;
1310
 
      table->setVariableWidth();
1311
1356
      key_part_info->field= new Field_varstring(table->getInsertRecord(),
1312
1357
                                                (uint32_t) key_part_info->length,
1313
1358
                                                0,
1314
1359
                                                (unsigned char*) 0,
1315
1360
                                                (uint32_t) 0,
1316
1361
                                                NULL,
 
1362
                                                table->getMutableShare(),
1317
1363
                                                &my_charset_bin);
1318
1364
      if (!key_part_info->field)
1319
1365
        goto err;
1357
1403
 
1358
1404
  if (session->is_fatal_error)                          // If end of memory
1359
1405
    goto err;
1360
 
  table->getMutableShare()->db_record_offset= 1;
1361
 
  if (table->getShare()->db_type() == myisam_engine)
 
1406
  share->db_record_offset= 1;
 
1407
  if (share->db_type() == myisam_engine)
1362
1408
  {
1363
1409
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
1364
1410
                                       &param->recinfo, select_options))
1381
1427
 
1382
1428
/****************************************************************************/
1383
1429
 
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;
 
1430
/**
 
1431
  Create a reduced Table object with properly set up Field list from a
 
1432
  list of field definitions.
 
1433
 
 
1434
    The created table doesn't have a table Cursor associated with
 
1435
    it, has no keys, no group/distinct, no copy_funcs array.
 
1436
    The sole purpose of this Table object is to use the power of Field
 
1437
    class to read/write data to/from table->getInsertRecord(). Then one can store
 
1438
    the record in any container (RB tree, hash, etc).
 
1439
    The table is created in Session mem_root, so are the table's fields.
 
1440
    Consequently, if you don't BLOB fields, you don't need to free it.
 
1441
 
 
1442
  @param session         connection handle
 
1443
  @param field_list  list of column definitions
 
1444
 
 
1445
  @return
 
1446
    0 if out of memory, Table object in case of success
 
1447
*/
 
1448
 
 
1449
Table *Session::create_virtual_tmp_table(List<CreateField> &field_list)
 
1450
{
 
1451
  uint32_t field_count= field_list.elements;
 
1452
  uint32_t blob_count= 0;
 
1453
  Field **field;
 
1454
  CreateField *cdef;                           /* column definition */
 
1455
  uint32_t record_length= 0;
 
1456
  uint32_t null_count= 0;                 /* number of columns which may be null */
 
1457
  uint32_t null_pack_length;              /* NULL representation array length */
 
1458
  unsigned char *bitmaps;
 
1459
  Table *table;
 
1460
 
 
1461
  TableShareInstance *share= getTemporaryShare(message::Table::INTERNAL); // This will not go into the tableshare cache, so no key is used.
 
1462
 
 
1463
  if (! share->getMemRoot()->multi_alloc_root(0,
 
1464
                                              &bitmaps, bitmap_buffer_size(field_count)*2,
 
1465
                                              NULL))
 
1466
  {
 
1467
    return NULL;
 
1468
  }
 
1469
 
 
1470
  table= share->getTable();
 
1471
  share->setFields(field_count + 1);
 
1472
  table->setFields(share->getFields(true));
 
1473
  field= share->getFields(true);
 
1474
  share->blob_field.resize(field_count+1);
 
1475
  share->fields= field_count;
 
1476
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
1477
  table->setup_tmp_table_column_bitmaps(bitmaps);
 
1478
 
 
1479
  table->in_use= this;           /* field->reset() may access table->in_use */
 
1480
 
 
1481
  /* Create all fields and calculate the total length of record */
 
1482
  List_iterator_fast<CreateField> it(field_list);
 
1483
  while ((cdef= it++))
 
1484
  {
 
1485
    *field= share->make_field(NULL,
 
1486
                              cdef->length,
 
1487
                              (cdef->flags & NOT_NULL_FLAG) ? false : true,
 
1488
                              (unsigned char *) ((cdef->flags & NOT_NULL_FLAG) ? 0 : ""),
 
1489
                              (cdef->flags & NOT_NULL_FLAG) ? 0 : 1,
 
1490
                              cdef->decimals,
 
1491
                              cdef->sql_type,
 
1492
                              cdef->charset,
 
1493
                              cdef->unireg_check,
 
1494
                              cdef->interval,
 
1495
                              cdef->field_name);
 
1496
    if (!*field)
 
1497
      goto error;
 
1498
    (*field)->init(table);
 
1499
    record_length+= (*field)->pack_length();
 
1500
    if (! ((*field)->flags & NOT_NULL_FLAG))
 
1501
      null_count++;
 
1502
 
 
1503
    if ((*field)->flags & BLOB_FLAG)
 
1504
      share->blob_field[blob_count++]= (uint32_t) (field - table->getFields());
 
1505
 
 
1506
    field++;
 
1507
  }
 
1508
  *field= NULL;                             /* mark the end of the list */
 
1509
  share->blob_field[blob_count]= 0;            /* mark the end of the list */
 
1510
  share->blob_fields= blob_count;
 
1511
 
 
1512
  null_pack_length= (null_count + 7)/8;
 
1513
  share->setRecordLength(record_length + null_pack_length);
 
1514
  share->rec_buff_length= ALIGN_SIZE(share->getRecordLength() + 1);
 
1515
  table->record[0]= (unsigned char*)alloc(share->rec_buff_length);
 
1516
  if (not table->getInsertRecord())
 
1517
    goto error;
 
1518
 
 
1519
  if (null_pack_length)
 
1520
  {
 
1521
    table->null_flags= (unsigned char*) table->getInsertRecord();
 
1522
    share->null_fields= null_count;
 
1523
    share->null_bytes= null_pack_length;
 
1524
  }
 
1525
  {
 
1526
    /* Set up field pointers */
 
1527
    unsigned char *null_pos= table->getInsertRecord();
 
1528
    unsigned char *field_pos= null_pos + share->null_bytes;
 
1529
    uint32_t null_bit= 1;
 
1530
 
 
1531
    for (field= table->getFields(); *field; ++field)
 
1532
    {
 
1533
      Field *cur_field= *field;
 
1534
      if ((cur_field->flags & NOT_NULL_FLAG))
 
1535
        cur_field->move_field(field_pos);
 
1536
      else
 
1537
      {
 
1538
        cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
 
1539
        null_bit<<= 1;
 
1540
        if (null_bit == (1 << 8))
 
1541
        {
 
1542
          ++null_pos;
 
1543
          null_bit= 1;
 
1544
        }
 
1545
      }
 
1546
      cur_field->reset();
 
1547
 
 
1548
      field_pos+= cur_field->pack_length();
 
1549
    }
 
1550
  }
 
1551
 
 
1552
  return table;
 
1553
 
 
1554
error:
 
1555
  for (field= table->getFields(); *field; ++field)
 
1556
  {
 
1557
    delete *field;                         /* just invokes field destructor */
 
1558
  }
 
1559
  return 0;
 
1560
}
 
1561
 
 
1562
bool Table::open_tmp_table()
 
1563
{
 
1564
  int error;
 
1565
  
 
1566
  TableIdentifier identifier(s->getSchemaName(), s->getTableName(), s->getPath());
 
1567
  if ((error=cursor->ha_open(identifier,
 
1568
                             this,
 
1569
                             s->getTableName(),
 
1570
                             O_RDWR,
 
1571
                             HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
 
1572
  {
 
1573
    print_error(error, MYF(0));
 
1574
    db_stat= 0;
 
1575
    return true;
 
1576
  }
 
1577
  (void) cursor->extra(HA_EXTRA_QUICK);         /* Faster */
 
1578
  return false;
 
1579
}
 
1580
 
 
1581
 
 
1582
/*
 
1583
  Create MyISAM temporary table
 
1584
 
 
1585
  SYNOPSIS
 
1586
    create_myisam_tmp_table()
 
1587
      keyinfo         Description of the index (there is always one index)
 
1588
      start_recinfo   MyISAM's column descriptions
 
1589
      recinfo INOUT   End of MyISAM's column descriptions
 
1590
      options         Option bits
 
1591
 
 
1592
  DESCRIPTION
 
1593
    Create a MyISAM temporary table according to passed description. The is
 
1594
    assumed to have one unique index or constraint.
 
1595
 
 
1596
    The passed array or MI_COLUMNDEF structures must have this form:
 
1597
 
 
1598
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
 
1599
         when there are many nullable columns)
 
1600
      2. Table columns
 
1601
      3. One free MI_COLUMNDEF element (*recinfo points here)
 
1602
 
 
1603
    This function may use the free element to create hash column for unique
 
1604
    constraint.
 
1605
 
 
1606
   RETURN
 
1607
     false - OK
 
1608
     true  - Error
 
1609
*/
 
1610
 
 
1611
bool Table::create_myisam_tmp_table(KeyInfo *keyinfo,
 
1612
                                    MI_COLUMNDEF *start_recinfo,
 
1613
                                    MI_COLUMNDEF **recinfo,
 
1614
                                    uint64_t options)
 
1615
{
 
1616
  int error;
 
1617
  MI_KEYDEF keydef;
 
1618
  MI_UNIQUEDEF uniquedef;
 
1619
  TableShare *share= s;
 
1620
 
 
1621
  if (share->sizeKeys())
 
1622
  {                                             // Get keys for ni_create
 
1623
    bool using_unique_constraint= false;
 
1624
    HA_KEYSEG *seg= (HA_KEYSEG*) this->mem_root.alloc_root(sizeof(*seg) * keyinfo->key_parts);
 
1625
    if (!seg)
 
1626
      goto err;
 
1627
 
 
1628
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
 
1629
    if (keyinfo->key_length >= cursor->getEngine()->max_key_length() ||
 
1630
        keyinfo->key_parts > cursor->getEngine()->max_key_parts() ||
 
1631
        share->uniques)
 
1632
    {
 
1633
      /* Can't create a key; Make a unique constraint instead of a key */
 
1634
      share->keys=    0;
 
1635
      share->uniques= 1;
 
1636
      using_unique_constraint= true;
 
1637
      memset(&uniquedef, 0, sizeof(uniquedef));
 
1638
      uniquedef.keysegs=keyinfo->key_parts;
 
1639
      uniquedef.seg=seg;
 
1640
      uniquedef.null_are_equal=1;
 
1641
 
 
1642
      /* Create extra column for hash value */
 
1643
      memset(*recinfo, 0, sizeof(**recinfo));
 
1644
      (*recinfo)->type= FIELD_CHECK;
 
1645
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
 
1646
      (*recinfo)++;
 
1647
      share->setRecordLength(share->getRecordLength() + MI_UNIQUE_HASH_LENGTH);
 
1648
    }
 
1649
    else
 
1650
    {
 
1651
      /* Create an unique key */
 
1652
      memset(&keydef, 0, sizeof(keydef));
 
1653
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
 
1654
      keydef.keysegs=  keyinfo->key_parts;
 
1655
      keydef.seg= seg;
 
1656
    }
 
1657
    for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
 
1658
    {
 
1659
      Field *key_field=keyinfo->key_part[i].field;
 
1660
      seg->flag=     0;
 
1661
      seg->language= key_field->charset()->number;
 
1662
      seg->length=   keyinfo->key_part[i].length;
 
1663
      seg->start=    keyinfo->key_part[i].offset;
 
1664
      if (key_field->flags & BLOB_FLAG)
 
1665
      {
 
1666
        seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
 
1667
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
 
1668
        seg->bit_start= (uint8_t)(key_field->pack_length()
 
1669
                                  - share->blob_ptr_size);
 
1670
        seg->flag= HA_BLOB_PART;
 
1671
        seg->length= 0;                 // Whole blob in unique constraint
 
1672
      }
 
1673
      else
 
1674
      {
 
1675
        seg->type= keyinfo->key_part[i].type;
 
1676
      }
 
1677
      if (!(key_field->flags & NOT_NULL_FLAG))
 
1678
      {
 
1679
        seg->null_bit= key_field->null_bit;
 
1680
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) getInsertRecord());
 
1681
        /*
 
1682
          We are using a GROUP BY on something that contains NULL
 
1683
          In this case we have to tell MyISAM that two NULL should
 
1684
          on INSERT be regarded at the same value
 
1685
        */
 
1686
        if (! using_unique_constraint)
 
1687
          keydef.flag|= HA_NULL_ARE_EQUAL;
 
1688
      }
 
1689
    }
 
1690
  }
 
1691
  MI_CREATE_INFO create_info;
 
1692
  memset(&create_info, 0, sizeof(create_info));
 
1693
 
 
1694
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
1695
      OPTION_BIG_TABLES)
 
1696
    create_info.data_file_length= ~(uint64_t) 0;
 
1697
 
 
1698
  if ((error=mi_create(share->getTableName(), share->sizeKeys(), &keydef,
 
1699
                       (uint32_t) (*recinfo-start_recinfo),
 
1700
                       start_recinfo,
 
1701
                       share->uniques, &uniquedef,
 
1702
                       &create_info,
 
1703
                       HA_CREATE_TMP_TABLE)))
 
1704
  {
 
1705
    print_error(error, MYF(0));
 
1706
    db_stat= 0;
 
1707
    goto err;
 
1708
  }
 
1709
  status_var_increment(in_use->status_var.created_tmp_disk_tables);
 
1710
  share->db_record_offset= 1;
 
1711
  return false;
 
1712
 err:
 
1713
  return true;
 
1714
}
 
1715
 
 
1716
 
 
1717
void Table::free_tmp_table(Session *session)
 
1718
{
 
1719
  memory::Root own_root= mem_root;
 
1720
  const char *save_proc_info;
 
1721
 
 
1722
  save_proc_info= session->get_proc_info();
 
1723
  session->set_proc_info("removing tmp table");
 
1724
 
 
1725
  // Release latches since this can take a long time
 
1726
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
1727
 
 
1728
  if (cursor)
 
1729
  {
 
1730
    if (db_stat)
 
1731
    {
 
1732
      cursor->closeMarkForDelete(s->getTableName());
 
1733
    }
 
1734
 
 
1735
    TableIdentifier identifier(s->getSchemaName(), s->getTableName(), s->getTableName());
 
1736
    s->db_type()->doDropTable(*session, identifier);
 
1737
 
 
1738
    delete cursor;
 
1739
  }
 
1740
 
 
1741
  /* free blobs */
 
1742
  for (Field **ptr= field ; *ptr ; ptr++)
 
1743
  {
 
1744
    (*ptr)->free();
 
1745
  }
 
1746
  free_io_cache();
 
1747
 
 
1748
  own_root.free_root(MYF(0)); /* the table is allocated in its own root */
 
1749
  session->set_proc_info(save_proc_info);
 
1750
}
 
1751
 
 
1752
my_bitmap_map *Table::use_all_columns(MyBitmap *bitmap)
 
1753
{
 
1754
  my_bitmap_map *old= bitmap->getBitmap();
 
1755
  bitmap->setBitmap(s->all_set.getBitmap());
1396
1756
  return old;
1397
1757
}
1398
1758
 
1399
 
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
 
1759
void Table::restore_column_map(my_bitmap_map *old)
1400
1760
{
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
 
  }
 
1761
  read_set->setBitmap(old);
1412
1762
}
1413
1763
 
1414
1764
uint32_t Table::find_shortest_key(const key_map *usable_keys)
1417
1767
  uint32_t best= MAX_KEY;
1418
1768
  if (usable_keys->any())
1419
1769
  {
1420
 
    for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
 
1770
    for (uint32_t nr= 0; nr < s->sizeKeys() ; nr++)
1421
1771
    {
1422
1772
      if (usable_keys->test(nr))
1423
1773
      {
1444
1794
{
1445
1795
  for (; *ptr ; ptr++)
1446
1796
  {
1447
 
    if ((*ptr)->cmp_offset(getShare()->rec_buff_length))
 
1797
    if ((*ptr)->cmp_offset(s->rec_buff_length))
1448
1798
      return true;
1449
1799
  }
1450
1800
  return false;
1451
1801
}
1452
1802
 
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
 
 
 
1803
/* Return false if row hasn't changed */
 
1804
 
 
1805
bool Table::compare_record()
 
1806
{
 
1807
  if (s->blob_fields + s->varchar_fields == 0)
 
1808
    return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) s->getRecordLength());
 
1809
  
1514
1810
  /* Compare null bits */
1515
 
  if (memcmp(null_flags, null_flags + getShare()->rec_buff_length, getShare()->null_bytes))
 
1811
  if (memcmp(null_flags, null_flags + s->rec_buff_length, s->null_bytes))
1516
1812
    return true; /* Diff in NULL value */
1517
1813
 
1518
1814
  /* Compare updated fields */
1519
1815
  for (Field **ptr= field ; *ptr ; ptr++)
1520
1816
  {
1521
 
    if (isWriteSet((*ptr)->position()) &&
1522
 
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
 
1817
    if (isWriteSet((*ptr)->field_index) &&
 
1818
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
1523
1819
      return true;
1524
1820
  }
1525
1821
  return false;
1531
1827
 */
1532
1828
void Table::storeRecord()
1533
1829
{
1534
 
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1830
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) s->getRecordLength());
1535
1831
}
1536
1832
 
1537
1833
/*
1540
1836
 */
1541
1837
void Table::storeRecordAsInsert()
1542
1838
{
1543
 
  assert(insert_values.size() >= getShare()->getRecordLength());
1544
 
  memcpy(&insert_values[0], getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1839
  assert(insert_values.size() >= s->getRecordLength());
 
1840
  memcpy(&insert_values[0], getInsertRecord(), (size_t) s->getRecordLength());
1545
1841
}
1546
1842
 
1547
1843
/*
1550
1846
 */
1551
1847
void Table::storeRecordAsDefault()
1552
1848
{
1553
 
  memcpy(getMutableShare()->getDefaultValues(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1849
  memcpy(s->getDefaultValues(), getInsertRecord(), (size_t) s->getRecordLength());
1554
1850
}
1555
1851
 
1556
1852
/*
1559
1855
 */
1560
1856
void Table::restoreRecord()
1561
1857
{
1562
 
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) getShare()->getRecordLength());
 
1858
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) s->getRecordLength());
1563
1859
}
1564
1860
 
1565
1861
/*
1568
1864
 */
1569
1865
void Table::restoreRecordAsDefault()
1570
1866
{
1571
 
  memcpy(getInsertRecord(), getMutableShare()->getDefaultValues(), (size_t) getShare()->getRecordLength());
 
1867
  memcpy(getInsertRecord(), s->getDefaultValues(), (size_t) s->getRecordLength());
1572
1868
}
1573
1869
 
1574
1870
/*
1578
1874
void Table::emptyRecord()
1579
1875
{
1580
1876
  restoreRecordAsDefault();
1581
 
  memset(null_flags, 255, getShare()->null_bytes);
 
1877
  memset(null_flags, 255, s->null_bytes);
1582
1878
}
1583
1879
 
1584
1880
Table::Table() : 
 
1881
  s(NULL),
1585
1882
  field(NULL),
1586
1883
  cursor(NULL),
1587
1884
  next(NULL),
1590
1887
  write_set(NULL),
1591
1888
  tablenr(0),
1592
1889
  db_stat(0),
1593
 
  def_read_set(),
1594
 
  def_write_set(),
1595
 
  tmp_set(),
1596
1890
  in_use(NULL),
1597
1891
  key_info(NULL),
1598
1892
  next_number_field(NULL),
1600
1894
  timestamp_field(NULL),
1601
1895
  pos_in_table_list(NULL),
1602
1896
  group(NULL),
 
1897
  alias(NULL),
1603
1898
  null_flags(NULL),
1604
1899
  lock_position(0),
1605
1900
  lock_data_start(0),
1626
1921
  quick_condition_rows(0),
1627
1922
  timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
1628
1923
  map(0),
1629
 
  quick_rows(),
1630
 
  const_key_parts(),
1631
 
  quick_key_parts(),
1632
 
  quick_n_ranges()
 
1924
  is_placeholder_created(0)
1633
1925
{
 
1926
  memset(&def_read_set, 0, sizeof(MyBitmap)); /**< Default read set of columns */
 
1927
  memset(&def_write_set, 0, sizeof(MyBitmap)); /**< Default write set of columns */
 
1928
  memset(&tmp_set, 0, sizeof(MyBitmap)); /* Not sure about this... */
 
1929
 
1634
1930
  record[0]= (unsigned char *) 0;
1635
1931
  record[1]= (unsigned char *) 0;
 
1932
 
 
1933
  reginfo.reset();
 
1934
  covering_keys.reset();
 
1935
  quick_keys.reset();
 
1936
  merge_keys.reset();
 
1937
 
 
1938
  keys_in_use_for_query.reset();
 
1939
  keys_in_use_for_group_by.reset();
 
1940
  keys_in_use_for_order_by.reset();
 
1941
 
 
1942
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
 
1943
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
 
1944
 
 
1945
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
 
1946
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
 
1947
 
 
1948
  memset(&mem_root, 0, sizeof(memory::Root));
 
1949
  memset(&sort, 0, sizeof(filesort_info_st));
1636
1950
}
1637
1951
 
1638
1952
/*****************************************************************************
1654
1968
    print them to the .err log
1655
1969
  */
1656
1970
  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());
 
1971
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
 
1972
                  error, s->getPath());
1659
1973
  print_error(error, MYF(0));
1660
1974
 
1661
1975
  return 1;
1678
1992
  tablenr= table_number;
1679
1993
  map= (table_map) 1 << table_number;
1680
1994
  force_index= table_list->force_index;
1681
 
  covering_keys= getShare()->keys_for_keyread;
 
1995
  covering_keys= s->keys_for_keyread;
1682
1996
  merge_keys.reset();
1683
1997
}
1684
1998
 
1698
2012
  return false;
1699
2013
}
1700
2014
 
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
2015
} /* namespace drizzled */