~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/heap/ha_heap.cc

Merge of Jay

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
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>
 
23
 
 
24
#include "heap.h"
18
25
#include "ha_heap.h"
19
26
#include "heapdef.h"
20
27
 
21
 
static handler *heap_create_handler(handlerton *hton,
22
 
                                    TABLE_SHARE *table, 
23
 
                                    MEM_ROOT *mem_root);
24
 
 
25
 
int heap_deinit(void *p __attribute__((unused)))
26
 
            
27
 
{
28
 
  return hp_panic(HA_PANIC_CLOSE);
 
28
#include <string>
 
29
 
 
30
using namespace std;
 
31
 
 
32
static const string engine_name("MEMORY");
 
33
 
 
34
pthread_mutex_t THR_LOCK_heap= PTHREAD_MUTEX_INITIALIZER;
 
35
 
 
36
static const char *ha_heap_exts[] = {
 
37
  NULL
 
38
};
 
39
 
 
40
class HeapEngine : public StorageEngine
 
41
{
 
42
public:
 
43
  HeapEngine(string name_arg) : StorageEngine(name_arg, HTON_CAN_RECREATE|HTON_TEMPORARY_ONLY)
 
44
  {
 
45
    addAlias("HEAP");
 
46
  }
 
47
 
 
48
  virtual handler *create(TableShare *table,
 
49
                          MEM_ROOT *mem_root)
 
50
  {
 
51
    return new (mem_root) ha_heap(this, table);
 
52
  }
 
53
 
 
54
  const char **bas_ext() const {
 
55
    return ha_heap_exts;
 
56
  }
 
57
 
 
58
  int createTableImplementation(Session *session, const char *table_name,
 
59
                                Table *table_arg, HA_CREATE_INFO *create_info,
 
60
                                drizzled::message::Table*);
 
61
 
 
62
  /* For whatever reason, internal tables can be created by handler::open()
 
63
     for HEAP.
 
64
     Instead of diving down a rat hole, let's just cry ourselves to sleep
 
65
     at night with this odd hackish workaround.
 
66
   */
 
67
  int heap_create_table(Session *session, const char *table_name,
 
68
                        Table *table_arg, HA_CREATE_INFO *create_info,
 
69
                        bool internal_table,
 
70
                        HP_SHARE **internal_share);
 
71
 
 
72
  int renameTableImplementation(Session*, const char * from, const char * to);
 
73
 
 
74
  int deleteTableImplementation(Session *, const string table_path);
 
75
};
 
76
 
 
77
/*
 
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.
 
80
*/
 
81
int HeapEngine::deleteTableImplementation(Session*, const string table_path)
 
82
{
 
83
  return heap_delete_table(table_path.c_str());
29
84
}
30
85
 
 
86
static HeapEngine *heap_storage_engine= NULL;
31
87
 
32
 
int heap_init(void *p)
 
88
static int heap_init(drizzled::plugin::Registry &registry)
33
89
{
34
 
  handlerton *heap_hton;
35
 
 
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;
41
 
 
 
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);
42
93
  return 0;
43
94
}
44
95
 
45
 
static handler *heap_create_handler(handlerton *hton,
46
 
                                    TABLE_SHARE *table, 
47
 
                                    MEM_ROOT *mem_root)
 
96
static int heap_deinit(drizzled::plugin::Registry &registry)
48
97
{
49
 
  return new (mem_root) ha_heap(hton, table);
 
98
  registry.remove(heap_storage_engine);
 
99
  delete heap_storage_engine;
 
100
 
 
101
  int ret= hp_panic(HA_PANIC_CLOSE);
 
102
 
 
103
  pthread_mutex_destroy(&THR_LOCK_heap);
 
104
 
 
105
  return ret;
50
106
}
51
107
 
52
108
 
 
109
 
53
110
/*****************************************************************************
54
111
** HEAP tables
55
112
*****************************************************************************/
56
113
 
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),
59
116
  internal_table(0)
60
117
{}
61
118
 
62
 
 
63
 
static const char *ha_heap_exts[] = {
64
 
  NullS
65
 
};
66
 
 
67
 
const char **ha_heap::bas_ext() const
68
 
{
69
 
  return ha_heap_exts;
70
 
}
71
 
 
72
119
/*
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
76
123
  immediate update.
77
124
 
78
125
  NOTE
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.
82
129
*/
83
130
#define HEAP_STATS_UPDATE_THRESHOLD 10
84
131
 
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)
86
133
{
87
134
  if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(name, mode)) && my_errno == ENOENT))
88
135
  {
90
137
    internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
91
138
    memset(&create_info, 0, sizeof(create_info));
92
139
    file= 0;
93
 
    if (!create(name, table, &create_info))
 
140
    HP_SHARE *internal_share= NULL;
 
141
    if (!heap_storage_engine->heap_create_table(ha_session(), name, table,
 
142
                                                &create_info,
 
143
                                                internal_table,&internal_share))
94
144
    {
95
145
        file= internal_table ?
96
146
          heap_open_from_share(internal_share, mode) :
133
183
  Create a copy of this table
134
184
 
135
185
  DESCRIPTION
136
 
    Do same as default implementation but use file->s->name instead of 
 
186
    Do same as default implementation but use file->s->name instead of
137
187
    table->s->path. This is needed by Windows where the clone() call sees
138
 
    '/'-delimited path in table->s->path, while ha_peap::open() was called 
 
188
    '/'-delimited path in table->s->path, while ha_peap::open() was called
139
189
    with '\'-delimited path.
140
190
*/
141
191
 
149
199
}
150
200
 
151
201
 
 
202
const char *ha_heap::index_type(uint32_t inx)
 
203
{
 
204
  return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
 
205
          "BTREE" : "HASH");
 
206
}
 
207
 
 
208
 
 
209
uint32_t ha_heap::index_flags(uint32_t inx, uint32_t, bool) const
 
210
{
 
211
  return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
 
212
          HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE :
 
213
          HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
 
214
}
 
215
 
 
216
 
152
217
/*
153
218
  Compute which keys to use for scanning
154
219
 
167
232
 
168
233
void ha_heap::set_keys_for_scanning(void)
169
234
{
170
 
  btree_keys.clear_all();
171
 
  for (uint i= 0 ; i < table->s->keys ; i++)
 
235
  btree_keys.reset();
 
236
  for (uint32_t i= 0 ; i < table->s->keys ; i++)
172
237
  {
173
238
    if (table->key_info[i].algorithm == HA_KEY_ALG_BTREE)
174
 
      btree_keys.set_bit(i);
 
239
      btree_keys.set(i);
175
240
  }
176
241
}
177
242
 
178
243
 
179
244
void ha_heap::update_key_stats()
180
245
{
181
 
  for (uint i= 0; i < table->s->keys; i++)
 
246
  for (uint32_t i= 0; i < table->s->keys; i++)
182
247
  {
183
248
    KEY *key=table->key_info+i;
184
249
    if (!key->rec_per_key)
190
255
      else
191
256
      {
192
257
        ha_rows hash_buckets= file->s->keydef[i].hash_buckets;
193
 
        uint no_records= hash_buckets ? (uint) (file->s->records/hash_buckets) : 2;
 
258
        uint32_t no_records= hash_buckets ? (uint) (file->s->records/hash_buckets) : 2;
194
259
        if (no_records < 2)
195
260
          no_records= 2;
196
261
        key->rec_per_key[key->key_parts-1]= no_records;
203
268
}
204
269
 
205
270
 
206
 
int ha_heap::write_row(uchar * buf)
 
271
int ha_heap::write_row(unsigned char * buf)
207
272
{
208
273
  int res;
209
274
  ha_statistic_increment(&SSV::ha_write_count);
210
 
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
211
 
    table->timestamp_field->set_time();
212
275
  if (table->next_number_field && buf == table->record[0])
213
276
  {
214
277
    if ((res= update_auto_increment()))
215
278
      return res;
216
279
  }
217
280
  res= heap_write(file,buf);
218
 
  if (!res && (++records_changed*HEAP_STATS_UPDATE_THRESHOLD > 
 
281
  if (!res && (++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
219
282
               file->s->records))
220
283
  {
221
284
    /*
227
290
  return res;
228
291
}
229
292
 
230
 
int ha_heap::update_row(const uchar * old_data, uchar * new_data)
 
293
int ha_heap::update_row(const unsigned char * old_data, unsigned char * new_data)
231
294
{
232
295
  int res;
233
296
  ha_statistic_increment(&SSV::ha_update_count);
234
297
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
235
298
    table->timestamp_field->set_time();
236
299
  res= heap_update(file,old_data,new_data);
237
 
  if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > 
 
300
  if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
238
301
              file->s->records)
239
302
  {
240
303
    /*
246
309
  return res;
247
310
}
248
311
 
249
 
int ha_heap::delete_row(const uchar * buf)
 
312
int ha_heap::delete_row(const unsigned char * buf)
250
313
{
251
314
  int res;
252
315
  ha_statistic_increment(&SSV::ha_delete_count);
253
316
  res= heap_delete(file,buf);
254
 
  if (!res && table->s->tmp_table == NO_TMP_TABLE && 
 
317
  if (!res && table->s->tmp_table == NO_TMP_TABLE &&
255
318
      ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
256
319
  {
257
320
    /*
263
326
  return res;
264
327
}
265
328
 
266
 
int ha_heap::index_read_map(uchar *buf, const uchar *key,
 
329
int ha_heap::index_read_map(unsigned char *buf, const unsigned char *key,
267
330
                            key_part_map keypart_map,
268
331
                            enum ha_rkey_function find_flag)
269
332
{
274
337
  return error;
275
338
}
276
339
 
277
 
int ha_heap::index_read_last_map(uchar *buf, const uchar *key,
 
340
int ha_heap::index_read_last_map(unsigned char *buf, const unsigned char *key,
278
341
                                 key_part_map keypart_map)
279
342
{
280
343
  assert(inited==INDEX);
285
348
  return error;
286
349
}
287
350
 
288
 
int ha_heap::index_read_idx_map(uchar *buf, uint index, const uchar *key,
 
351
int ha_heap::index_read_idx_map(unsigned char *buf, uint32_t index, const unsigned char *key,
289
352
                                key_part_map keypart_map,
290
353
                                enum ha_rkey_function find_flag)
291
354
{
295
358
  return error;
296
359
}
297
360
 
298
 
int ha_heap::index_next(uchar * buf)
 
361
int ha_heap::index_next(unsigned char * buf)
299
362
{
300
363
  assert(inited==INDEX);
301
364
  ha_statistic_increment(&SSV::ha_read_next_count);
304
367
  return error;
305
368
}
306
369
 
307
 
int ha_heap::index_prev(uchar * buf)
 
370
int ha_heap::index_prev(unsigned char * buf)
308
371
{
309
372
  assert(inited==INDEX);
310
373
  ha_statistic_increment(&SSV::ha_read_prev_count);
313
376
  return error;
314
377
}
315
378
 
316
 
int ha_heap::index_first(uchar * buf)
 
379
int ha_heap::index_first(unsigned char * buf)
317
380
{
318
381
  assert(inited==INDEX);
319
382
  ha_statistic_increment(&SSV::ha_read_first_count);
322
385
  return error;
323
386
}
324
387
 
325
 
int ha_heap::index_last(uchar * buf)
 
388
int ha_heap::index_last(unsigned char * buf)
326
389
{
327
390
  assert(inited==INDEX);
328
391
  ha_statistic_increment(&SSV::ha_read_last_count);
336
399
  return scan ? heap_scan_init(file) : 0;
337
400
}
338
401
 
339
 
int ha_heap::rnd_next(uchar *buf)
 
402
int ha_heap::rnd_next(unsigned char *buf)
340
403
{
341
404
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
342
405
  int error=heap_scan(file, buf);
344
407
  return error;
345
408
}
346
409
 
347
 
int ha_heap::rnd_pos(uchar * buf, uchar *pos)
 
410
int ha_heap::rnd_pos(unsigned char * buf, unsigned char *pos)
348
411
{
349
412
  int error;
350
413
  HEAP_PTR heap_position;
355
418
  return error;
356
419
}
357
420
 
358
 
void ha_heap::position(const uchar *record __attribute__((unused)))
 
421
void ha_heap::position(const unsigned char *)
359
422
{
360
423
  *(HEAP_PTR*) ref= heap_position(file);        // Ref is aligned
361
424
}
362
425
 
363
 
int ha_heap::info(uint flag)
 
426
int ha_heap::info(uint32_t flag)
364
427
{
365
428
  HEAPINFO hp_info;
366
429
  (void) heap_info(file,&hp_info,flag);
420
483
  return 0;
421
484
}
422
485
 
423
 
int ha_heap::external_lock(THD *thd __attribute__((unused)),
424
 
                           int lock_type __attribute__((unused)))
 
486
int ha_heap::external_lock(Session *, int)
425
487
{
426
488
  return 0;                                     // No external locking
427
489
}
451
513
    HA_ERR_WRONG_COMMAND  mode not implemented.
452
514
*/
453
515
 
454
 
int ha_heap::disable_indexes(uint mode)
 
516
int ha_heap::disable_indexes(uint32_t mode)
455
517
{
456
518
  int error;
457
519
 
498
560
    HA_ERR_WRONG_COMMAND  mode not implemented.
499
561
*/
500
562
 
501
 
int ha_heap::enable_indexes(uint mode)
 
563
int ha_heap::enable_indexes(uint32_t mode)
502
564
{
503
565
  int error;
504
566
 
534
596
  return heap_indexes_are_disabled(file);
535
597
}
536
598
 
537
 
THR_LOCK_DATA **ha_heap::store_lock(THD *thd __attribute__((unused)),
 
599
THR_LOCK_DATA **ha_heap::store_lock(Session *,
538
600
                                    THR_LOCK_DATA **to,
539
601
                                    enum thr_lock_type lock_type)
540
602
{
544
606
  return to;
545
607
}
546
608
 
547
 
/*
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.
550
 
*/
551
 
 
552
 
int ha_heap::delete_table(const char *name)
553
 
{
554
 
  int error= heap_delete_table(name);
555
 
  return error == ENOENT ? 0 : error;
556
 
}
557
 
 
558
 
 
559
 
void ha_heap::drop_table(const char *name __attribute__((unused)))
 
609
void ha_heap::drop_table(const char *)
560
610
{
561
611
  file->s->delete_on_close= 1;
562
612
  close();
563
613
}
564
614
 
565
615
 
566
 
int ha_heap::rename_table(const char * from, const char * to)
 
616
int HeapEngine::renameTableImplementation(Session*,
 
617
                                          const char *from, const char *to)
567
618
{
568
619
  return heap_rename(from,to);
569
620
}
570
621
 
571
622
 
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)
574
625
{
575
626
  KEY *key=table->key_info+inx;
591
642
  return key->rec_per_key[key->key_parts-1];
592
643
}
593
644
 
594
 
 
595
 
int ha_heap::create(const char *name, TABLE *table_arg,
596
 
                    HA_CREATE_INFO *create_info)
597
 
{
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,
 
647
                                          Table *table_arg,
 
648
                                          HA_CREATE_INFO *create_info,
 
649
                                          drizzled::message::Table*)
 
650
{
 
651
  HP_SHARE *internal_share;
 
652
  return heap_create_table(session, table_name, table_arg, create_info,
 
653
                           false, &internal_share);
 
654
}
 
655
 
 
656
 
 
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)
 
660
{
 
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;
604
667
  HA_KEYSEG *seg;
605
668
  char buff[FN_REFLEN];
606
669
  int error;
607
 
  TABLE_SHARE *share= table_arg->s;
 
670
  TableShare *share= table_arg->s;
608
671
  bool found_real_auto_increment= 0;
609
672
 
610
 
  if (!(columndef= (HP_COLUMNDEF*) my_malloc(column_count * sizeof(HP_COLUMNDEF), MYF(MY_WME))))
 
673
  /* 
 
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.
 
678
   */
 
679
  uint64_t num_rows= share->getMaxRows();
 
680
  if (num_rows > UINT32_MAX)
 
681
    return -1;
 
682
 
 
683
  if (!(columndef= (HP_COLUMNDEF*) malloc(column_count * sizeof(HP_COLUMNDEF))))
611
684
    return my_errno;
612
685
 
613
686
  for (column_idx= 0; column_idx < column_count; column_idx++)
621
694
    if (field->null_bit)
622
695
    {
623
696
      column->null_bit= field->null_bit;
624
 
      column->null_pos= (uint) (field->null_ptr - (uchar*) table_arg->record[0]);
 
697
      column->null_pos= (uint) (field->null_ptr - (unsigned char*) table_arg->record[0]);
625
698
    }
626
699
    else
627
700
    {
642
715
  for (key= parts= 0; key < keys; key++)
643
716
    parts+= table_arg->key_info[key].key_parts;
644
717
 
645
 
  if (!(keydef= (HP_KEYDEF*) my_malloc(keys * sizeof(HP_KEYDEF) +
646
 
                                       parts * sizeof(HA_KEYSEG),
647
 
                                       MYF(MY_WME))))
 
718
  if (!(keydef= (HP_KEYDEF*) malloc(keys * sizeof(HP_KEYDEF) +
 
719
                                    parts * sizeof(HA_KEYSEG))))
648
720
  {
649
 
    my_free((void *) columndef, MYF(0));
 
721
    free((void *) columndef);
650
722
    return my_errno;
651
723
  }
652
724
 
653
 
  seg= my_reinterpret_cast(HA_KEYSEG*) (keydef + keys);
 
725
  seg= reinterpret_cast<HA_KEYSEG*> (keydef + keys);
654
726
  for (key= 0; key < keys; key++)
655
727
  {
656
728
    KEY *pos= table_arg->key_info+key;
711
783
      if (field->null_ptr)
712
784
      {
713
785
        seg->null_bit= field->null_bit;
714
 
        seg->null_pos= (uint) (field->null_ptr - (uchar*) table_arg->record[0]);
 
786
        seg->null_pos= (uint) (field->null_ptr - (unsigned char*) table_arg->record[0]);
715
787
      }
716
788
      else
717
789
      {
736
808
      }
737
809
    }
738
810
  }
739
 
  
 
811
 
740
812
  if (key_part_size < share->null_bytes + ((share->last_null_bit_pos+7) >> 3))
741
813
  {
742
814
    /* Make sure to include null fields regardless of the presense of keys */
743
815
    key_part_size = share->null_bytes + ((share->last_null_bit_pos+7) >> 3);
744
816
  }
745
817
 
746
 
  
747
 
  
 
818
 
 
819
 
748
820
  if (table_arg->found_next_number_field)
749
821
  {
750
822
    keydef[share->next_number_index].flag|= HA_AUTO_KEY;
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),
765
 
                   keys, keydef,
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);
771
 
  
772
 
  my_free((uchar*) keydef, MYF(0));
773
 
  my_free((void *) columndef, MYF(0));
774
 
  assert(file == 0);
 
835
 
 
836
  error= heap_create(fn_format(buff,table_name,"","",
 
837
                              MY_REPLACE_EXT|MY_UNPACK_FILENAME),
 
838
                    keys, keydef,
 
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. */
 
843
                    0, // Factor out MIN
 
844
                    &hp_create_info, internal_share);
 
845
 
 
846
  free((unsigned char*) keydef);
 
847
  free((void *) columndef);
 
848
 
775
849
  return (error);
776
850
}
777
851
 
778
852
 
779
 
void ha_heap::update_create_info(HA_CREATE_INFO *create_info)
780
 
{
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))
785
 
  {
786
 
    if (file->s->recordspace.is_variable_size)
787
 
      create_info->block_size= file->s->recordspace.chunk_length;
788
 
    else
789
 
      create_info->block_size= 0;
790
 
  }
791
 
}
792
 
 
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)
798
856
{
803
861
}
804
862
 
805
863
 
806
 
bool ha_heap::check_if_incompatible_data(HA_CREATE_INFO *info,
807
 
                                         uint table_changes)
 
864
int ha_heap::cmp_ref(const unsigned char *ref1, const unsigned char *ref2)
808
865
{
809
 
  /* Check that auto_increment value was not changed */
810
 
  if ((info->used_fields & HA_CREATE_USED_AUTO &&
811
 
       info->auto_increment_value != 0) ||
812
 
      table_changes == IS_EQUAL_NO ||
813
 
      table_changes & IS_EQUAL_PACK_LENGTH) // Not implemented yet
814
 
    return COMPATIBLE_DATA_NO;
815
 
  return COMPATIBLE_DATA_YES;
 
866
  return memcmp(ref1, ref2, sizeof(HEAP_PTR));
816
867
}
817
868
 
818
 
mysql_declare_plugin(heap)
 
869
 
 
870
drizzle_declare_plugin(heap)
819
871
{
820
 
  DRIZZLE_STORAGE_ENGINE_PLUGIN,
821
872
  "MEMORY",
822
873
  "1.0",
823
874
  "MySQL AB",
829
880
  NULL,                       /* system variables                */
830
881
  NULL                        /* config options                  */
831
882
}
832
 
mysql_declare_plugin_end;
 
883
drizzle_declare_plugin_end;