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 */
16
#define DRIZZLE_SERVER 1
17
#include <drizzled/server_includes.h>
17
#ifdef USE_PRAGMA_IMPLEMENTATION
18
#pragma implementation // gcc: Class implementation
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"
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;
82
90
#define HEAP_STATS_UPDATE_THRESHOLD 10
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)
86
94
if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(name, mode)) && my_errno == ENOENT))
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));
92
100
if (!create(name, table, &create_info))
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)
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;
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)
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);
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)
297
int ha_heap::index_next(unsigned char * buf)
305
int ha_heap::index_next(uchar * buf)
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;
306
int ha_heap::index_prev(unsigned char * buf)
314
int ha_heap::index_prev(uchar * buf)
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;
315
int ha_heap::index_first(unsigned char * buf)
323
int ha_heap::index_first(uchar * buf)
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;
324
int ha_heap::index_last(unsigned char * buf)
332
int ha_heap::index_last(uchar * buf)
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;
338
int ha_heap::rnd_next(unsigned char *buf)
346
int ha_heap::rnd_next(uchar *buf)
340
348
ha_statistic_increment(&SSV::ha_read_rnd_next_count);
341
349
int error=heap_scan(file, buf);
346
int ha_heap::rnd_pos(unsigned char * buf, unsigned char *pos)
354
int ha_heap::rnd_pos(uchar * buf, uchar *pos)
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;
357
void ha_heap::position(const unsigned char *record __attribute__((unused)))
365
void ha_heap::position(const uchar *record __attribute__((__unused__)))
359
367
*(HEAP_PTR*) ref= heap_position(file); // Ref is aligned
362
int ha_heap::info(uint32_t flag)
370
int ha_heap::info(uint flag)
364
372
HEAPINFO hp_info;
365
373
(void) heap_info(file,&hp_info,flag);
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__)))
425
425
return 0; // No external locking
586
586
return stats.records;
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];
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)
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;
602
600
HP_KEYDEF *keydef;
604
char buff[FN_REFLEN];
606
603
TABLE_SHARE *share= table_arg->s;
607
604
bool found_real_auto_increment= 0;
609
if (!(columndef= (HP_COLUMNDEF*) my_malloc(column_count * sizeof(HP_COLUMNDEF), MYF(MY_WME))))
612
for (column_idx= 0; column_idx < column_count; column_idx++)
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]);
622
column->null_bit= field->null_bit;
623
column->null_pos= (uint) (field->null_ptr - (unsigned char*) table_arg->record[0]);
631
if (field->type() == DRIZZLE_TYPE_VARCHAR)
633
column->length_bytes= (uint8_t)(((Field_varstring*)field)->length_bytes);
637
column->length_bytes= 0;
641
606
for (key= parts= 0; key < keys; key++)
642
607
parts+= table_arg->key_info[key].key_parts;
644
609
if (!(keydef= (HP_KEYDEF*) my_malloc(keys * sizeof(HP_KEYDEF) +
645
610
parts * sizeof(HA_KEYSEG),
648
free((void *) columndef);
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++)
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)
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*);
674
assert(0); // cannot happen
635
DBUG_ASSERT(0); // cannot happen
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;
696
next_field_pos= seg->start + seg->length;
697
if (field->type() == DRIZZLE_TYPE_VARCHAR)
699
next_field_pos+= (uint8_t)(((Field_varstring*)field)->length_bytes);
702
if (next_field_pos > key_part_size) {
703
key_part_size= next_field_pos;
706
657
if (field->flags & (ENUM_FLAG | SET_FLAG))
707
658
seg->charset= &my_charset_bin;
728
679
auto_key= key+ 1;
729
680
auto_key_type= field->key_type();
731
if ((uint)field->field_index + 1 > max_key_fieldnr)
733
/* Do not use seg->fieldnr as it's not reliable in case of temp tables */
734
max_key_fieldnr= field->field_index + 1;
739
if (key_part_size < share->null_bytes + ((share->last_null_bit_pos+7) >> 3))
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);
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)
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),
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);
771
free((unsigned char*) keydef);
772
free((void *) columndef);
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 &&
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);
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))
785
if (file->s->recordspace.is_variable_size)
786
create_info->block_size= file->s->recordspace.chunk_length;
788
create_info->block_size= 0;
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)
814
742
return COMPATIBLE_DATA_YES;
745
struct st_mysql_storage_engine heap_storage_engine=
746
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
817
748
mysql_declare_plugin(heap)
819
DRIZZLE_STORAGE_ENGINE_PLUGIN,
750
MYSQL_STORAGE_ENGINE_PLUGIN,
751
&heap_storage_engine,
823
754
"Hash based, stored in memory, useful for temporary tables",
824
755
PLUGIN_LICENSE_GPL,
827
759
NULL, /* status variables */
828
760
NULL, /* system variables */
829
761
NULL /* config options */