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
16
#include <drizzled/server_includes.h>
17
#include <drizzled/error.h>
18
#include <drizzled/table.h>
19
#include <drizzled/session.h>
20
#include <drizzled/current_session.h>
21
#include <drizzled/field/timestamp.h>
22
#include <drizzled/field/varstring.h>
18
25
#include "ha_heap.h"
19
26
#include "heapdef.h"
21
static handler *heap_create_handler(handlerton *hton,
25
int heap_deinit(void *p __attribute__((unused)))
28
return hp_panic(HA_PANIC_CLOSE);
32
static const string engine_name("MEMORY");
34
pthread_mutex_t THR_LOCK_heap= PTHREAD_MUTEX_INITIALIZER;
36
static const char *ha_heap_exts[] = {
40
class HeapEngine : public StorageEngine
43
HeapEngine(string name_arg) : StorageEngine(name_arg, HTON_CAN_RECREATE|HTON_TEMPORARY_ONLY)
48
virtual handler *create(TableShare *table,
51
return new (mem_root) ha_heap(this, table);
54
const char **bas_ext() const {
58
int createTableImplementation(Session *session, const char *table_name,
59
Table *table_arg, HA_CREATE_INFO *create_info,
60
drizzled::message::Table*);
62
/* For whatever reason, internal tables can be created by handler::open()
64
Instead of diving down a rat hole, let's just cry ourselves to sleep
65
at night with this odd hackish workaround.
67
int heap_create_table(Session *session, const char *table_name,
68
Table *table_arg, HA_CREATE_INFO *create_info,
70
HP_SHARE **internal_share);
72
int renameTableImplementation(Session*, const char * from, const char * to);
74
int deleteTableImplementation(Session *, const string table_path);
78
We have to ignore ENOENT entries as the HEAP table is created on open and
79
not when doing a CREATE on the table.
81
int HeapEngine::deleteTableImplementation(Session*, const string table_path)
83
return heap_delete_table(table_path.c_str());
86
static HeapEngine *heap_storage_engine= NULL;
32
int heap_init(void *p)
88
static int heap_init(drizzled::plugin::Registry ®istry)
34
handlerton *heap_hton;
36
heap_hton= (handlerton *)p;
37
heap_hton->state= SHOW_OPTION_YES;
38
heap_hton->db_type= DB_TYPE_HEAP;
39
heap_hton->create= heap_create_handler;
40
heap_hton->flags= HTON_CAN_RECREATE;
90
heap_storage_engine= new HeapEngine(engine_name);
91
registry.add(heap_storage_engine);
92
pthread_mutex_init(&THR_LOCK_heap, MY_MUTEX_INIT_FAST);
45
static handler *heap_create_handler(handlerton *hton,
96
static int heap_deinit(drizzled::plugin::Registry ®istry)
49
return new (mem_root) ha_heap(hton, table);
98
registry.remove(heap_storage_engine);
99
delete heap_storage_engine;
101
int ret= hp_panic(HA_PANIC_CLOSE);
103
pthread_mutex_destroy(&THR_LOCK_heap);
53
110
/*****************************************************************************
55
112
*****************************************************************************/
57
ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg)
58
:handler(hton, table_arg), file(0), records_changed(0), key_stat_version(0),
114
ha_heap::ha_heap(StorageEngine *engine_arg, TableShare *table_arg)
115
:handler(engine_arg, table_arg), file(0), records_changed(0), key_stat_version(0),
63
static const char *ha_heap_exts[] = {
67
const char **ha_heap::bas_ext() const
73
Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to
74
rec_per_key) after 1/HEAP_STATS_UPDATE_THRESHOLD fraction of table records
75
have been inserted/updated/deleted. delete_all_rows() and table flush cause
120
Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to
121
rec_per_key) after 1/HEAP_STATS_UPDATE_THRESHOLD fraction of table records
122
have been inserted/updated/deleted. delete_all_rows() and table flush cause
79
126
hash index statistics must be updated when number of table records changes
80
from 0 to non-zero value and vice versa. Otherwise records_in_range may
127
from 0 to non-zero value and vice versa. Otherwise records_in_range may
81
128
erroneously return 0 and 'range' may miss records.
83
130
#define HEAP_STATS_UPDATE_THRESHOLD 10
85
int ha_heap::open(const char *name, int mode, uint test_if_locked)
132
int ha_heap::open(const char *name, int mode, uint32_t test_if_locked)
87
134
if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(name, mode)) && my_errno == ENOENT))
548
We have to ignore ENOENT entries as the HEAP table is created on open and
549
not when doing a CREATE on the table.
552
int ha_heap::delete_table(const char *name)
554
int error= heap_delete_table(name);
555
return error == ENOENT ? 0 : error;
559
void ha_heap::drop_table(const char *name __attribute__((unused)))
609
void ha_heap::drop_table(const char *)
561
611
file->s->delete_on_close= 1;
566
int ha_heap::rename_table(const char * from, const char * to)
616
int HeapEngine::renameTableImplementation(Session*,
617
const char *from, const char *to)
568
619
return heap_rename(from,to);
572
ha_rows ha_heap::records_in_range(uint inx, key_range *min_key,
623
ha_rows ha_heap::records_in_range(uint32_t inx, key_range *min_key,
573
624
key_range *max_key)
575
626
KEY *key=table->key_info+inx;
591
642
return key->rec_per_key[key->key_parts-1];
595
int ha_heap::create(const char *name, TABLE *table_arg,
596
HA_CREATE_INFO *create_info)
598
uint key, parts, mem_per_row_keys= 0, keys= table_arg->s->keys;
599
uint auto_key= 0, auto_key_type= 0;
600
uint max_key_fieldnr = 0, key_part_size = 0, next_field_pos = 0;
601
uint column_idx, column_count= table_arg->s->fields;
645
int HeapEngine::createTableImplementation(Session *session,
646
const char *table_name,
648
HA_CREATE_INFO *create_info,
649
drizzled::message::Table*)
651
HP_SHARE *internal_share;
652
return heap_create_table(session, table_name, table_arg, create_info,
653
false, &internal_share);
657
int HeapEngine::heap_create_table(Session *session, const char *table_name,
658
Table *table_arg, HA_CREATE_INFO *create_info,
659
bool internal_table, HP_SHARE **internal_share)
661
uint32_t key, parts, mem_per_row_keys= 0, keys= table_arg->s->keys;
662
uint32_t auto_key= 0, auto_key_type= 0;
663
uint32_t max_key_fieldnr = 0, key_part_size = 0, next_field_pos = 0;
664
uint32_t column_idx, column_count= table_arg->s->fields;
602
665
HP_COLUMNDEF *columndef;
603
666
HP_KEYDEF *keydef;
605
668
char buff[FN_REFLEN];
607
TABLE_SHARE *share= table_arg->s;
670
TableShare *share= table_arg->s;
608
671
bool found_real_auto_increment= 0;
610
if (!(columndef= (HP_COLUMNDEF*) my_malloc(column_count * sizeof(HP_COLUMNDEF), MYF(MY_WME))))
674
* We cannot create tables with more rows than UINT32_MAX. This is a
675
* limitation of the HEAP engine. Here, since TableShare::getMaxRows()
676
* can return a number more than that, we trap it here instead of casting
677
* to a truncated integer.
679
uint64_t num_rows= share->getMaxRows();
680
if (num_rows > UINT32_MAX)
683
if (!(columndef= (HP_COLUMNDEF*) malloc(column_count * sizeof(HP_COLUMNDEF))))
613
686
for (column_idx= 0; column_idx < column_count; column_idx++)
755
827
hp_create_info.auto_key_type= auto_key_type;
756
828
hp_create_info.auto_increment= (create_info->auto_increment_value ?
757
829
create_info->auto_increment_value - 1 : 0);
758
hp_create_info.max_table_size=current_thd->variables.max_heap_table_size;
830
hp_create_info.max_table_size=session->variables.max_heap_table_size;
759
831
hp_create_info.with_auto_increment= found_real_auto_increment;
760
832
hp_create_info.internal_table= internal_table;
761
833
hp_create_info.max_chunk_size= share->block_size;
762
834
hp_create_info.is_dynamic= (share->row_type == ROW_TYPE_DYNAMIC);
763
error= heap_create(fn_format(buff,name,"","",
764
MY_REPLACE_EXT|MY_UNPACK_FILENAME),
766
column_count, columndef,
767
max_key_fieldnr, key_part_size,
768
share->reclength, mem_per_row_keys,
769
(uint32_t) share->max_rows, (uint32_t) share->min_rows,
770
&hp_create_info, &internal_share);
772
my_free((uchar*) keydef, MYF(0));
773
my_free((void *) columndef, MYF(0));
836
error= heap_create(fn_format(buff,table_name,"","",
837
MY_REPLACE_EXT|MY_UNPACK_FILENAME),
839
column_count, columndef,
840
max_key_fieldnr, key_part_size,
841
share->reclength, mem_per_row_keys,
842
static_cast<uint32_t>(num_rows), /* We check for overflow above, so cast is fine here. */
844
&hp_create_info, internal_share);
846
free((unsigned char*) keydef);
847
free((void *) columndef);
779
void ha_heap::update_create_info(HA_CREATE_INFO *create_info)
781
table->file->info(HA_STATUS_AUTO);
782
if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
783
create_info->auto_increment_value= stats.auto_increment_value;
784
if (!(create_info->used_fields & HA_CREATE_USED_BLOCK_SIZE))
786
if (file->s->recordspace.is_variable_size)
787
create_info->block_size= file->s->recordspace.chunk_length;
789
create_info->block_size= 0;
793
void ha_heap::get_auto_increment(uint64_t offset __attribute__((unused)),
794
uint64_t increment __attribute__((unused)),
795
uint64_t nb_desired_values __attribute__((unused)),
853
void ha_heap::get_auto_increment(uint64_t, uint64_t, uint64_t,
796
854
uint64_t *first_value,
797
855
uint64_t *nb_reserved_values)