~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/heap/ha_heap.cc

Removed dead variable, sorted authors file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
 
#define DRIZZLE_SERVER 1
17
 
#include <drizzled/server_includes.h>
 
16
 
 
17
#ifdef USE_PRAGMA_IMPLEMENTATION
 
18
#pragma implementation                          // gcc: Class implementation
 
19
#endif
 
20
 
 
21
#define MYSQL_SERVER 1
 
22
#include "mysql_priv.h"
 
23
#include <mysql/plugin.h>
18
24
#include "ha_heap.h"
19
25
#include "heapdef.h"
20
26
 
22
28
                                    TABLE_SHARE *table, 
23
29
                                    MEM_ROOT *mem_root);
24
30
 
25
 
int heap_deinit(void *p __attribute__((unused)))
26
 
            
 
31
int heap_panic(handlerton *hton __attribute__((__unused__)),
 
32
               ha_panic_function flag)
27
33
{
28
 
  return hp_panic(HA_PANIC_CLOSE);
 
34
  return hp_panic(flag);
29
35
}
30
36
 
31
37
 
35
41
 
36
42
  heap_hton= (handlerton *)p;
37
43
  heap_hton->state=      SHOW_OPTION_YES;
 
44
  heap_hton->db_type=    DB_TYPE_HEAP;
38
45
  heap_hton->create=     heap_create_handler;
 
46
  heap_hton->panic=      heap_panic;
39
47
  heap_hton->flags=      HTON_CAN_RECREATE;
40
48
 
41
49
  return 0;
60
68
 
61
69
 
62
70
static const char *ha_heap_exts[] = {
63
 
  NULL
 
71
  NullS
64
72
};
65
73
 
66
74
const char **ha_heap::bas_ext() const
81
89
*/
82
90
#define HEAP_STATS_UPDATE_THRESHOLD 10
83
91
 
84
 
int ha_heap::open(const char *name, int mode, uint32_t test_if_locked)
 
92
int ha_heap::open(const char *name, int mode, uint test_if_locked)
85
93
{
86
94
  if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(name, mode)) && my_errno == ENOENT))
87
95
  {
88
96
    HA_CREATE_INFO create_info;
89
97
    internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
90
 
    memset(&create_info, 0, sizeof(create_info));
 
98
    bzero(&create_info, sizeof(create_info));
91
99
    file= 0;
92
100
    if (!create(name, table, &create_info))
93
101
    {
167
175
void ha_heap::set_keys_for_scanning(void)
168
176
{
169
177
  btree_keys.clear_all();
170
 
  for (uint32_t i= 0 ; i < table->s->keys ; i++)
 
178
  for (uint i= 0 ; i < table->s->keys ; i++)
171
179
  {
172
180
    if (table->key_info[i].algorithm == HA_KEY_ALG_BTREE)
173
181
      btree_keys.set_bit(i);
177
185
 
178
186
void ha_heap::update_key_stats()
179
187
{
180
 
  for (uint32_t i= 0; i < table->s->keys; i++)
 
188
  for (uint i= 0; i < table->s->keys; i++)
181
189
  {
182
190
    KEY *key=table->key_info+i;
183
191
    if (!key->rec_per_key)
189
197
      else
190
198
      {
191
199
        ha_rows hash_buckets= file->s->keydef[i].hash_buckets;
192
 
        uint32_t no_records= hash_buckets ? (uint) (file->s->records/hash_buckets) : 2;
 
200
        uint no_records= hash_buckets ? (uint) (file->s->records/hash_buckets) : 2;
193
201
        if (no_records < 2)
194
202
          no_records= 2;
195
203
        key->rec_per_key[key->key_parts-1]= no_records;
202
210
}
203
211
 
204
212
 
205
 
int ha_heap::write_row(unsigned char * buf)
 
213
int ha_heap::write_row(uchar * buf)
206
214
{
207
215
  int res;
208
216
  ha_statistic_increment(&SSV::ha_write_count);
226
234
  return res;
227
235
}
228
236
 
229
 
int ha_heap::update_row(const unsigned char * old_data, unsigned char * new_data)
 
237
int ha_heap::update_row(const uchar * old_data, uchar * new_data)
230
238
{
231
239
  int res;
232
240
  ha_statistic_increment(&SSV::ha_update_count);
245
253
  return res;
246
254
}
247
255
 
248
 
int ha_heap::delete_row(const unsigned char * buf)
 
256
int ha_heap::delete_row(const uchar * buf)
249
257
{
250
258
  int res;
251
259
  ha_statistic_increment(&SSV::ha_delete_count);
262
270
  return res;
263
271
}
264
272
 
265
 
int ha_heap::index_read_map(unsigned char *buf, const unsigned char *key,
 
273
int ha_heap::index_read_map(uchar *buf, const uchar *key,
266
274
                            key_part_map keypart_map,
267
275
                            enum ha_rkey_function find_flag)
268
276
{
269
 
  assert(inited==INDEX);
 
277
  DBUG_ASSERT(inited==INDEX);
270
278
  ha_statistic_increment(&SSV::ha_read_key_count);
271
279
  int error = heap_rkey(file,buf,active_index, key, keypart_map, find_flag);
272
280
  table->status = error ? STATUS_NOT_FOUND : 0;
273
281
  return error;
274
282
}
275
283
 
276
 
int ha_heap::index_read_last_map(unsigned char *buf, const unsigned char *key,
 
284
int ha_heap::index_read_last_map(uchar *buf, const uchar *key,
277
285
                                 key_part_map keypart_map)
278
286
{
279
 
  assert(inited==INDEX);
 
287
  DBUG_ASSERT(inited==INDEX);
280
288
  ha_statistic_increment(&SSV::ha_read_key_count);
281
289
  int error= heap_rkey(file, buf, active_index, key, keypart_map,
282
290
                       HA_READ_PREFIX_LAST);
284
292
  return error;
285
293
}
286
294
 
287
 
int ha_heap::index_read_idx_map(unsigned char *buf, uint32_t index, const unsigned char *key,
 
295
int ha_heap::index_read_idx_map(uchar *buf, uint index, const uchar *key,
288
296
                                key_part_map keypart_map,
289
297
                                enum ha_rkey_function find_flag)
290
298
{
294
302
  return error;
295
303
}
296
304
 
297
 
int ha_heap::index_next(unsigned char * buf)
 
305
int ha_heap::index_next(uchar * buf)
298
306
{
299
 
  assert(inited==INDEX);
 
307
  DBUG_ASSERT(inited==INDEX);
300
308
  ha_statistic_increment(&SSV::ha_read_next_count);
301
309
  int error=heap_rnext(file,buf);
302
310
  table->status=error ? STATUS_NOT_FOUND: 0;
303
311
  return error;
304
312
}
305
313
 
306
 
int ha_heap::index_prev(unsigned char * buf)
 
314
int ha_heap::index_prev(uchar * buf)
307
315
{
308
 
  assert(inited==INDEX);
 
316
  DBUG_ASSERT(inited==INDEX);
309
317
  ha_statistic_increment(&SSV::ha_read_prev_count);
310
318
  int error=heap_rprev(file,buf);
311
319
  table->status=error ? STATUS_NOT_FOUND: 0;
312
320
  return error;
313
321
}
314
322
 
315
 
int ha_heap::index_first(unsigned char * buf)
 
323
int ha_heap::index_first(uchar * buf)
316
324
{
317
 
  assert(inited==INDEX);
 
325
  DBUG_ASSERT(inited==INDEX);
318
326
  ha_statistic_increment(&SSV::ha_read_first_count);
319
327
  int error=heap_rfirst(file, buf, active_index);
320
328
  table->status=error ? STATUS_NOT_FOUND: 0;
321
329
  return error;
322
330
}
323
331
 
324
 
int ha_heap::index_last(unsigned char * buf)
 
332
int ha_heap::index_last(uchar * buf)
325
333
{
326
 
  assert(inited==INDEX);
 
334
  DBUG_ASSERT(inited==INDEX);
327
335
  ha_statistic_increment(&SSV::ha_read_last_count);
328
336
  int error=heap_rlast(file, buf, active_index);
329
337
  table->status=error ? STATUS_NOT_FOUND: 0;
335
343
  return scan ? heap_scan_init(file) : 0;
336
344
}
337
345
 
338
 
int ha_heap::rnd_next(unsigned char *buf)
 
346
int ha_heap::rnd_next(uchar *buf)
339
347
{
340
348
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
341
349
  int error=heap_scan(file, buf);
343
351
  return error;
344
352
}
345
353
 
346
 
int ha_heap::rnd_pos(unsigned char * buf, unsigned char *pos)
 
354
int ha_heap::rnd_pos(uchar * buf, uchar *pos)
347
355
{
348
356
  int error;
349
357
  HEAP_PTR heap_position;
350
358
  ha_statistic_increment(&SSV::ha_read_rnd_count);
351
 
  memcpy(&heap_position, pos, sizeof(HEAP_PTR));
 
359
  memcpy_fixed((char*) &heap_position, pos, sizeof(HEAP_PTR));
352
360
  error=heap_rrnd(file, buf, heap_position);
353
361
  table->status=error ? STATUS_NOT_FOUND: 0;
354
362
  return error;
355
363
}
356
364
 
357
 
void ha_heap::position(const unsigned char *record __attribute__((unused)))
 
365
void ha_heap::position(const uchar *record __attribute__((__unused__)))
358
366
{
359
367
  *(HEAP_PTR*) ref= heap_position(file);        // Ref is aligned
360
368
}
361
369
 
362
 
int ha_heap::info(uint32_t flag)
 
370
int ha_heap::info(uint flag)
363
371
{
364
372
  HEAPINFO hp_info;
365
373
  (void) heap_info(file,&hp_info,flag);
385
393
}
386
394
 
387
395
 
388
 
enum row_type ha_heap::get_row_type() const
389
 
{
390
 
  if (file->s->recordspace.is_variable_size)
391
 
    return ROW_TYPE_DYNAMIC;
392
 
 
393
 
  return ROW_TYPE_FIXED;
394
 
}
395
 
 
396
396
int ha_heap::extra(enum ha_extra_function operation)
397
397
{
398
398
  return heap_extra(file,operation);
419
419
  return 0;
420
420
}
421
421
 
422
 
int ha_heap::external_lock(THD *thd __attribute__((unused)),
423
 
                           int lock_type __attribute__((unused)))
 
422
int ha_heap::external_lock(THD *thd __attribute__((__unused__)),
 
423
                           int lock_type __attribute__((__unused__)))
424
424
{
425
425
  return 0;                                     // No external locking
426
426
}
450
450
    HA_ERR_WRONG_COMMAND  mode not implemented.
451
451
*/
452
452
 
453
 
int ha_heap::disable_indexes(uint32_t mode)
 
453
int ha_heap::disable_indexes(uint mode)
454
454
{
455
455
  int error;
456
456
 
497
497
    HA_ERR_WRONG_COMMAND  mode not implemented.
498
498
*/
499
499
 
500
 
int ha_heap::enable_indexes(uint32_t mode)
 
500
int ha_heap::enable_indexes(uint mode)
501
501
{
502
502
  int error;
503
503
 
533
533
  return heap_indexes_are_disabled(file);
534
534
}
535
535
 
536
 
THR_LOCK_DATA **ha_heap::store_lock(THD *thd __attribute__((unused)),
 
536
THR_LOCK_DATA **ha_heap::store_lock(THD *thd __attribute__((__unused__)),
537
537
                                    THR_LOCK_DATA **to,
538
538
                                    enum thr_lock_type lock_type)
539
539
{
555
555
}
556
556
 
557
557
 
558
 
void ha_heap::drop_table(const char *name __attribute__((unused)))
 
558
void ha_heap::drop_table(const char *name __attribute__((__unused__)))
559
559
{
560
560
  file->s->delete_on_close= 1;
561
561
  close();
568
568
}
569
569
 
570
570
 
571
 
ha_rows ha_heap::records_in_range(uint32_t inx, key_range *min_key,
 
571
ha_rows ha_heap::records_in_range(uint inx, key_range *min_key,
572
572
                                  key_range *max_key)
573
573
{
574
574
  KEY *key=table->key_info+inx;
586
586
    return stats.records;
587
587
 
588
588
  /* Assert that info() did run. We need current statistics here. */
589
 
  assert(key_stat_version == file->s->key_stat_version);
 
589
  DBUG_ASSERT(key_stat_version == file->s->key_stat_version);
590
590
  return key->rec_per_key[key->key_parts-1];
591
591
}
592
592
 
593
593
 
594
 
int ha_heap::create(const char *name, Table *table_arg,
 
594
int ha_heap::create(const char *name, TABLE *table_arg,
595
595
                    HA_CREATE_INFO *create_info)
596
596
{
597
 
  uint32_t key, parts, mem_per_row_keys= 0, keys= table_arg->s->keys;
598
 
  uint32_t auto_key= 0, auto_key_type= 0;
599
 
  uint32_t max_key_fieldnr = 0, key_part_size = 0, next_field_pos = 0;
600
 
  uint32_t column_idx, column_count= table_arg->s->fields;
601
 
  HP_COLUMNDEF *columndef;
 
597
  uint key, parts, mem_per_row= 0, keys= table_arg->s->keys;
 
598
  uint auto_key= 0, auto_key_type= 0;
 
599
  ha_rows max_rows;
602
600
  HP_KEYDEF *keydef;
603
601
  HA_KEYSEG *seg;
604
 
  char buff[FN_REFLEN];
605
602
  int error;
606
603
  TABLE_SHARE *share= table_arg->s;
607
604
  bool found_real_auto_increment= 0;
608
605
 
609
 
  if (!(columndef= (HP_COLUMNDEF*) my_malloc(column_count * sizeof(HP_COLUMNDEF), MYF(MY_WME))))
610
 
    return my_errno;
611
 
 
612
 
  for (column_idx= 0; column_idx < column_count; column_idx++)
613
 
  {
614
 
    Field* field= *(table_arg->field + column_idx);
615
 
    HP_COLUMNDEF* column= columndef + column_idx;
616
 
    column->type= (uint16_t)field->type();
617
 
    column->length= field->pack_length();
618
 
    column->offset= field->offset(field->table->record[0]);
619
 
 
620
 
    if (field->null_bit)
621
 
    {
622
 
      column->null_bit= field->null_bit;
623
 
      column->null_pos= (uint) (field->null_ptr - (unsigned char*) table_arg->record[0]);
624
 
    }
625
 
    else
626
 
    {
627
 
      column->null_bit= 0;
628
 
      column->null_pos= 0;
629
 
    }
630
 
 
631
 
    if (field->type() == DRIZZLE_TYPE_VARCHAR)
632
 
    {
633
 
      column->length_bytes= (uint8_t)(((Field_varstring*)field)->length_bytes);
634
 
    }
635
 
    else
636
 
    {
637
 
      column->length_bytes= 0;
638
 
    }
639
 
  }
640
 
 
641
606
  for (key= parts= 0; key < keys; key++)
642
607
    parts+= table_arg->key_info[key].key_parts;
643
608
 
644
609
  if (!(keydef= (HP_KEYDEF*) my_malloc(keys * sizeof(HP_KEYDEF) +
645
610
                                       parts * sizeof(HA_KEYSEG),
646
611
                                       MYF(MY_WME))))
647
 
  {
648
 
    free((void *) columndef);
649
612
    return my_errno;
650
 
  }
651
 
 
652
 
  seg= reinterpret_cast<HA_KEYSEG*> (keydef + keys);
 
613
  seg= my_reinterpret_cast(HA_KEYSEG*) (keydef + keys);
653
614
  for (key= 0; key < keys; key++)
654
615
  {
655
616
    KEY *pos= table_arg->key_info+key;
664
625
    case HA_KEY_ALG_UNDEF:
665
626
    case HA_KEY_ALG_HASH:
666
627
      keydef[key].algorithm= HA_KEY_ALG_HASH;
667
 
      mem_per_row_keys+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
 
628
      mem_per_row+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
668
629
      break;
669
630
    case HA_KEY_ALG_BTREE:
670
631
      keydef[key].algorithm= HA_KEY_ALG_BTREE;
671
 
      mem_per_row_keys+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*);
 
632
      mem_per_row+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*);
672
633
      break;
673
634
    default:
674
 
      assert(0); // cannot happen
 
635
      DBUG_ASSERT(0); // cannot happen
675
636
    }
676
637
 
677
638
    for (; key_part != key_part_end; key_part++, seg++)
693
654
      seg->length=  (uint) key_part->length;
694
655
      seg->flag=    key_part->key_part_flag;
695
656
 
696
 
      next_field_pos= seg->start + seg->length;
697
 
      if (field->type() == DRIZZLE_TYPE_VARCHAR)
698
 
      {
699
 
        next_field_pos+= (uint8_t)(((Field_varstring*)field)->length_bytes);
700
 
      }
701
 
 
702
 
      if (next_field_pos > key_part_size) {
703
 
        key_part_size= next_field_pos;
704
 
      }
705
 
 
706
657
      if (field->flags & (ENUM_FLAG | SET_FLAG))
707
658
        seg->charset= &my_charset_bin;
708
659
      else
710
661
      if (field->null_ptr)
711
662
      {
712
663
        seg->null_bit= field->null_bit;
713
 
        seg->null_pos= (uint) (field->null_ptr - (unsigned char*) table_arg->record[0]);
 
664
        seg->null_pos= (uint) (field->null_ptr - (uchar*) table_arg->record[0]);
714
665
      }
715
666
      else
716
667
      {
728
679
        auto_key= key+ 1;
729
680
        auto_key_type= field->key_type();
730
681
      }
731
 
      if ((uint)field->field_index + 1 > max_key_fieldnr)
732
 
      {
733
 
        /* Do not use seg->fieldnr as it's not reliable in case of temp tables */
734
 
        max_key_fieldnr= field->field_index + 1;
735
 
      }
736
682
    }
737
683
  }
738
 
  
739
 
  if (key_part_size < share->null_bytes + ((share->last_null_bit_pos+7) >> 3))
740
 
  {
741
 
    /* Make sure to include null fields regardless of the presense of keys */
742
 
    key_part_size = share->null_bytes + ((share->last_null_bit_pos+7) >> 3);
743
 
  }
744
 
 
745
 
  
746
 
  
 
684
  mem_per_row+= MY_ALIGN(share->reclength + 1, sizeof(char*));
 
685
  max_rows = (ha_rows) (table_arg->in_use->variables.max_heap_table_size /
 
686
                        (uint64_t) mem_per_row);
747
687
  if (table_arg->found_next_number_field)
748
688
  {
749
689
    keydef[share->next_number_index].flag|= HA_AUTO_KEY;
757
697
  hp_create_info.max_table_size=current_thd->variables.max_heap_table_size;
758
698
  hp_create_info.with_auto_increment= found_real_auto_increment;
759
699
  hp_create_info.internal_table= internal_table;
760
 
  hp_create_info.max_chunk_size= share->block_size;
761
 
  hp_create_info.is_dynamic= (share->row_type == ROW_TYPE_DYNAMIC);
762
 
  error= heap_create(fn_format(buff,name,"","",
763
 
                               MY_REPLACE_EXT|MY_UNPACK_FILENAME),
764
 
                   keys, keydef,
765
 
         column_count, columndef,
766
 
         max_key_fieldnr, key_part_size,
767
 
         share->reclength, mem_per_row_keys,
768
 
         (uint32_t) share->max_rows, (uint32_t) share->min_rows,
769
 
         &hp_create_info, &internal_share);
770
 
  
771
 
  free((unsigned char*) keydef);
772
 
  free((void *) columndef);
773
 
  assert(file == 0);
 
700
  max_rows = (ha_rows) (hp_create_info.max_table_size / mem_per_row);
 
701
  error= heap_create(name,
 
702
                     keys, keydef, share->reclength,
 
703
                     (ulong) ((share->max_rows < max_rows &&
 
704
                               share->max_rows) ? 
 
705
                              share->max_rows : max_rows),
 
706
                     (ulong) share->min_rows, &hp_create_info, &internal_share);
 
707
  my_free((uchar*) keydef, MYF(0));
 
708
  DBUG_ASSERT(file == 0);
774
709
  return (error);
775
710
}
776
711
 
780
715
  table->file->info(HA_STATUS_AUTO);
781
716
  if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
782
717
    create_info->auto_increment_value= stats.auto_increment_value;
783
 
  if (!(create_info->used_fields & HA_CREATE_USED_BLOCK_SIZE))
784
 
  {
785
 
    if (file->s->recordspace.is_variable_size)
786
 
      create_info->block_size= file->s->recordspace.chunk_length;
787
 
    else
788
 
      create_info->block_size= 0;
789
 
  }
790
718
}
791
719
 
792
 
void ha_heap::get_auto_increment(uint64_t offset __attribute__((unused)),
793
 
                                 uint64_t increment __attribute__((unused)),
794
 
                                 uint64_t nb_desired_values __attribute__((unused)),
 
720
void ha_heap::get_auto_increment(uint64_t offset __attribute__((__unused__)),
 
721
                                 uint64_t increment __attribute__((__unused__)),
 
722
                                 uint64_t nb_desired_values __attribute__((__unused__)),
795
723
                                 uint64_t *first_value,
796
724
                                 uint64_t *nb_reserved_values)
797
725
{
803
731
 
804
732
 
805
733
bool ha_heap::check_if_incompatible_data(HA_CREATE_INFO *info,
806
 
                                         uint32_t table_changes)
 
734
                                         uint table_changes)
807
735
{
808
736
  /* Check that auto_increment value was not changed */
809
737
  if ((info->used_fields & HA_CREATE_USED_AUTO &&
814
742
  return COMPATIBLE_DATA_YES;
815
743
}
816
744
 
 
745
struct st_mysql_storage_engine heap_storage_engine=
 
746
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
 
747
 
817
748
mysql_declare_plugin(heap)
818
749
{
819
 
  DRIZZLE_STORAGE_ENGINE_PLUGIN,
 
750
  MYSQL_STORAGE_ENGINE_PLUGIN,
 
751
  &heap_storage_engine,
820
752
  "MEMORY",
821
 
  "1.0",
822
753
  "MySQL AB",
823
754
  "Hash based, stored in memory, useful for temporary tables",
824
755
  PLUGIN_LICENSE_GPL,
825
756
  heap_init,
826
 
  heap_deinit,
 
757
  NULL,
 
758
  0x0100, /* 1.0 */
827
759
  NULL,                       /* status variables                */
828
760
  NULL,                       /* system variables                */
829
761
  NULL                        /* config options                  */