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 drizzled::plugin::StorageEngine
43
HeapEngine(string name_arg)
44
: drizzled::plugin::StorageEngine(name_arg,
45
HTON_CAN_RECREATE|HTON_TEMPORARY_ONLY)
50
virtual handler *create(TableShare *table,
53
return new (mem_root) ha_heap(this, table);
56
const char **bas_ext() const {
60
int createTableImplementation(Session *session, const char *table_name,
61
Table *table_arg, HA_CREATE_INFO *create_info,
62
drizzled::message::Table*);
64
/* For whatever reason, internal tables can be created by handler::open()
66
Instead of diving down a rat hole, let's just cry ourselves to sleep
67
at night with this odd hackish workaround.
69
int heap_create_table(Session *session, const char *table_name,
70
Table *table_arg, HA_CREATE_INFO *create_info,
72
HP_SHARE **internal_share);
74
int renameTableImplementation(Session*, const char * from, const char * to);
76
int deleteTableImplementation(Session *, const string table_path);
80
We have to ignore ENOENT entries as the HEAP table is created on open and
81
not when doing a CREATE on the table.
83
int HeapEngine::deleteTableImplementation(Session*, const string table_path)
85
return heap_delete_table(table_path.c_str());
88
static HeapEngine *heap_storage_engine= NULL;
32
int heap_init(void *p)
90
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->create= heap_create_handler;
39
heap_hton->flags= HTON_CAN_RECREATE;
92
heap_storage_engine= new HeapEngine(engine_name);
93
registry.add(heap_storage_engine);
94
pthread_mutex_init(&THR_LOCK_heap, MY_MUTEX_INIT_FAST);
44
static handler *heap_create_handler(handlerton *hton,
98
static int heap_deinit(drizzled::plugin::Registry ®istry)
48
return new (mem_root) ha_heap(hton, table);
100
registry.remove(heap_storage_engine);
101
delete heap_storage_engine;
103
int ret= hp_panic(HA_PANIC_CLOSE);
105
pthread_mutex_destroy(&THR_LOCK_heap);
52
112
/*****************************************************************************
54
114
*****************************************************************************/
56
ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg)
57
:handler(hton, table_arg), file(0), records_changed(0), key_stat_version(0),
116
ha_heap::ha_heap(drizzled::plugin::StorageEngine *engine_arg,
117
TableShare *table_arg)
118
:handler(engine_arg, table_arg), file(0), records_changed(0), key_stat_version(0),
62
static const char *ha_heap_exts[] = {
66
const char **ha_heap::bas_ext() const
72
Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to
73
rec_per_key) after 1/HEAP_STATS_UPDATE_THRESHOLD fraction of table records
74
have been inserted/updated/deleted. delete_all_rows() and table flush cause
123
Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to
124
rec_per_key) after 1/HEAP_STATS_UPDATE_THRESHOLD fraction of table records
125
have been inserted/updated/deleted. delete_all_rows() and table flush cause
78
129
hash index statistics must be updated when number of table records changes
79
from 0 to non-zero value and vice versa. Otherwise records_in_range may
130
from 0 to non-zero value and vice versa. Otherwise records_in_range may
80
131
erroneously return 0 and 'range' may miss records.
82
133
#define HEAP_STATS_UPDATE_THRESHOLD 10
590
645
return key->rec_per_key[key->key_parts-1];
594
int ha_heap::create(const char *name, Table *table_arg,
595
HA_CREATE_INFO *create_info)
648
int HeapEngine::createTableImplementation(Session *session,
649
const char *table_name,
651
HA_CREATE_INFO *create_info,
652
drizzled::message::Table*)
654
HP_SHARE *internal_share;
655
return heap_create_table(session, table_name, table_arg, create_info,
656
false, &internal_share);
660
int HeapEngine::heap_create_table(Session *session, const char *table_name,
661
Table *table_arg, HA_CREATE_INFO *create_info,
662
bool internal_table, HP_SHARE **internal_share)
597
664
uint32_t key, parts, mem_per_row_keys= 0, keys= table_arg->s->keys;
598
665
uint32_t auto_key= 0, auto_key_type= 0;
754
830
hp_create_info.auto_key_type= auto_key_type;
755
831
hp_create_info.auto_increment= (create_info->auto_increment_value ?
756
832
create_info->auto_increment_value - 1 : 0);
757
hp_create_info.max_table_size=current_thd->variables.max_heap_table_size;
833
hp_create_info.max_table_size=session->variables.max_heap_table_size;
758
834
hp_create_info.with_auto_increment= found_real_auto_increment;
759
835
hp_create_info.internal_table= internal_table;
760
836
hp_create_info.max_chunk_size= share->block_size;
761
837
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);
839
error= heap_create(fn_format(buff,table_name,"","",
840
MY_REPLACE_EXT|MY_UNPACK_FILENAME),
842
column_count, columndef,
843
max_key_fieldnr, key_part_size,
844
share->reclength, mem_per_row_keys,
845
static_cast<uint32_t>(num_rows), /* We check for overflow above, so cast is fine here. */
847
&hp_create_info, internal_share);
771
849
free((unsigned char*) keydef);
772
850
free((void *) columndef);
778
void ha_heap::update_create_info(HA_CREATE_INFO *create_info)
780
table->file->info(HA_STATUS_AUTO);
781
if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
782
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)),
856
void ha_heap::get_auto_increment(uint64_t, uint64_t, uint64_t,
795
857
uint64_t *first_value,
796
858
uint64_t *nb_reserved_values)
805
bool ha_heap::check_if_incompatible_data(HA_CREATE_INFO *info,
806
uint32_t table_changes)
867
int ha_heap::cmp_ref(const unsigned char *ref1, const unsigned char *ref2)
808
/* Check that auto_increment value was not changed */
809
if ((info->used_fields & HA_CREATE_USED_AUTO &&
810
info->auto_increment_value != 0) ||
811
table_changes == IS_EQUAL_NO ||
812
table_changes & IS_EQUAL_PACK_LENGTH) // Not implemented yet
813
return COMPATIBLE_DATA_NO;
814
return COMPATIBLE_DATA_YES;
869
return memcmp(ref1, ref2, sizeof(HEAP_PTR));
817
mysql_declare_plugin(heap)
873
drizzle_declare_plugin(heap)
819
DRIZZLE_STORAGE_ENGINE_PLUGIN,