~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/heap/ha_heap.cc

  • Committer: Brian Aker
  • Date: 2009-08-15 00:59:30 UTC
  • mfrom: (1115.1.7 merge)
  • Revision ID: brian@gaz-20090815005930-q47yenjrq1esiwsz
Merge of Trond + Brian

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
 
#include "heap_priv.h"
 
16
#include <drizzled/server_includes.h>
17
17
#include <drizzled/error.h>
18
18
#include <drizzled/table.h>
19
19
#include <drizzled/session.h>
20
20
#include <drizzled/current_session.h>
21
21
#include <drizzled/field/timestamp.h>
22
22
#include <drizzled/field/varstring.h>
23
 
#include "drizzled/plugin/daemon.h"
24
23
 
25
24
#include "heap.h"
26
25
#include "ha_heap.h"
 
26
#include "heapdef.h"
27
27
 
28
28
#include <string>
29
29
 
30
 
 
31
 
using namespace drizzled;
32
30
using namespace std;
33
31
 
34
32
static const string engine_name("MEMORY");
39
37
  NULL
40
38
};
41
39
 
42
 
class HeapEngine : public plugin::StorageEngine
 
40
class HeapEngine : public StorageEngine
43
41
{
44
42
public:
45
 
  explicit HeapEngine(string name_arg) :
46
 
    plugin::StorageEngine(name_arg,
47
 
                          HTON_STATS_RECORDS_IS_EXACT |
48
 
                          HTON_NULL_IN_KEY |
49
 
                          HTON_FAST_KEY_READ |
50
 
                          HTON_NO_BLOBS |
51
 
                          HTON_HAS_RECORDS |
52
 
                          HTON_SKIP_STORE_LOCK |
53
 
                          HTON_TEMPORARY_ONLY)
54
 
  {
55
 
    pthread_mutex_init(&THR_LOCK_heap, MY_MUTEX_INIT_FAST);
56
 
  }
57
 
 
58
 
  virtual ~HeapEngine()
59
 
  {
60
 
    hp_panic(HA_PANIC_CLOSE);
61
 
 
62
 
    pthread_mutex_destroy(&THR_LOCK_heap);
63
 
  }
64
 
 
65
 
  virtual Cursor *create(TableShare &table,
66
 
                          memory::Root *mem_root)
67
 
  {
68
 
    return new (mem_root) ha_heap(*this, table);
 
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);
69
52
  }
70
53
 
71
54
  const char **bas_ext() const {
72
55
    return ha_heap_exts;
73
56
  }
74
57
 
75
 
  int doCreateTable(Session &session,
76
 
                    Table &table_arg,
77
 
                    drizzled::TableIdentifier &identifier,
78
 
                    message::Table &create_proto);
 
58
  int createTableImplementation(Session *session, const char *table_name,
 
59
                                Table *table_arg, HA_CREATE_INFO *create_info,
 
60
                                drizzled::message::Table*);
79
61
 
80
 
  /* For whatever reason, internal tables can be created by Cursor::open()
81
 
     for MEMORY.
 
62
  /* For whatever reason, internal tables can be created by handler::open()
 
63
     for HEAP.
82
64
     Instead of diving down a rat hole, let's just cry ourselves to sleep
83
65
     at night with this odd hackish workaround.
84
66
   */
85
67
  int heap_create_table(Session *session, const char *table_name,
86
 
                        Table *table_arg,
 
68
                        Table *table_arg, HA_CREATE_INFO *create_info,
87
69
                        bool internal_table,
88
 
                        message::Table &create_proto,
89
70
                        HP_SHARE **internal_share);
90
71
 
91
 
  int doRenameTable(Session&, TableIdentifier &from, TableIdentifier &to);
92
 
 
93
 
  int doDropTable(Session&, TableIdentifier &identifier);
94
 
 
95
 
  int doGetTableDefinition(Session& session,
96
 
                           TableIdentifier &identifier,
97
 
                           message::Table &table_message);
98
 
 
99
 
  /* Temp only engine, so do not return values. */
100
 
  void doGetTableNames(CachedDirectory &, SchemaIdentifier& , set<string>&) { };
101
 
 
102
 
  uint32_t max_supported_keys()          const { return MAX_KEY; }
103
 
  uint32_t max_supported_key_part_length() const { return MAX_KEY_LENGTH; }
104
 
 
105
 
  uint32_t index_flags(enum  ha_key_alg algorithm) const
106
 
  {
107
 
    return ((algorithm == HA_KEY_ALG_BTREE) ?
108
 
            HA_READ_NEXT |
109
 
            HA_READ_PREV |
110
 
            HA_READ_ORDER |
111
 
            HA_READ_RANGE :
112
 
            HA_ONLY_WHOLE_INDEX |
113
 
            HA_KEY_SCAN_NOT_ROR);
114
 
  }
115
 
 
116
 
  bool doDoesTableExist(Session& session, TableIdentifier &identifier);
117
 
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
118
 
                             drizzled::SchemaIdentifier &schema_identifier,
119
 
                             drizzled::TableIdentifiers &set_of_identifiers);
 
72
  int renameTableImplementation(Session*, const char * from, const char * to);
 
73
 
 
74
  int deleteTableImplementation(Session *, const string table_path);
120
75
};
121
76
 
122
 
void HeapEngine::doGetTableIdentifiers(drizzled::CachedDirectory&,
123
 
                                       drizzled::SchemaIdentifier&,
124
 
                                       drizzled::TableIdentifiers&)
125
 
{
126
 
}
127
 
 
128
 
bool HeapEngine::doDoesTableExist(Session& session, TableIdentifier &identifier)
129
 
{
130
 
  return session.doesTableMessageExist(identifier);
131
 
}
132
 
 
133
 
int HeapEngine::doGetTableDefinition(Session &session,
134
 
                                     TableIdentifier &identifier,
135
 
                                     message::Table &table_proto)
136
 
{
137
 
  if (session.getTableMessage(identifier, table_proto))
138
 
    return EEXIST;
139
 
 
140
 
  return ENOENT;
141
 
}
142
77
/*
143
 
  We have to ignore ENOENT entries as the MEMORY table is created on open and
 
78
  We have to ignore ENOENT entries as the HEAP table is created on open and
144
79
  not when doing a CREATE on the table.
145
80
*/
146
 
int HeapEngine::doDropTable(Session &session, TableIdentifier &identifier)
 
81
int HeapEngine::deleteTableImplementation(Session*, const string table_path)
147
82
{
148
 
  session.removeTableMessage(identifier);
149
 
 
150
 
  int error= heap_delete_table(identifier.getPath().c_str());
151
 
 
152
 
  if (error == ENOENT)
153
 
    error= 0;
154
 
 
155
 
  return error;
 
83
  return heap_delete_table(table_path.c_str());
156
84
}
157
85
 
158
86
static HeapEngine *heap_storage_engine= NULL;
159
87
 
160
 
static int heap_init(plugin::Context &context)
 
88
static int heap_init(drizzled::plugin::Registry &registry)
161
89
{
162
90
  heap_storage_engine= new HeapEngine(engine_name);
163
 
  context.add(heap_storage_engine);
 
91
  registry.add(heap_storage_engine);
 
92
  pthread_mutex_init(&THR_LOCK_heap, MY_MUTEX_INIT_FAST);
164
93
  return 0;
165
94
}
166
95
 
 
96
static int heap_deinit(drizzled::plugin::Registry &registry)
 
97
{
 
98
  registry.remove(heap_storage_engine);
 
99
  delete heap_storage_engine;
 
100
 
 
101
  pthread_mutex_destroy(&THR_LOCK_heap);
 
102
 
 
103
  return hp_panic(HA_PANIC_CLOSE);
 
104
}
 
105
 
 
106
 
167
107
 
168
108
/*****************************************************************************
169
 
** MEMORY tables
 
109
** HEAP tables
170
110
*****************************************************************************/
171
111
 
172
 
ha_heap::ha_heap(plugin::StorageEngine &engine_arg,
173
 
                 TableShare &table_arg)
174
 
  :Cursor(engine_arg, table_arg), file(0), records_changed(0), key_stat_version(0),
 
112
ha_heap::ha_heap(StorageEngine *engine_arg, TableShare *table_arg)
 
113
  :handler(engine_arg, table_arg), file(0), records_changed(0), key_stat_version(0),
175
114
  internal_table(0)
176
115
{}
177
116
 
178
117
/*
179
118
  Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to
180
 
  rec_per_key) after 1/MEMORY_STATS_UPDATE_THRESHOLD fraction of table records
 
119
  rec_per_key) after 1/HEAP_STATS_UPDATE_THRESHOLD fraction of table records
181
120
  have been inserted/updated/deleted. delete_all_rows() and table flush cause
182
121
  immediate update.
183
122
 
186
125
   from 0 to non-zero value and vice versa. Otherwise records_in_range may
187
126
   erroneously return 0 and 'range' may miss records.
188
127
*/
189
 
#define MEMORY_STATS_UPDATE_THRESHOLD 10
 
128
#define HEAP_STATS_UPDATE_THRESHOLD 10
190
129
 
191
130
int ha_heap::open(const char *name, int mode, uint32_t test_if_locked)
192
131
{
193
 
  if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(name, mode)) && errno == ENOENT))
 
132
  if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(name, mode)) && my_errno == ENOENT))
194
133
  {
195
134
    HA_CREATE_INFO create_info;
196
135
    internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
197
136
    memset(&create_info, 0, sizeof(create_info));
198
137
    file= 0;
199
138
    HP_SHARE *internal_share= NULL;
200
 
    message::Table create_proto;
201
 
 
202
139
    if (!heap_storage_engine->heap_create_table(ha_session(), name, table,
203
 
                                                internal_table,
204
 
                                                create_proto,
205
 
                                                &internal_share))
 
140
                                                &create_info,
 
141
                                                internal_table,&internal_share))
206
142
    {
207
143
        file= internal_table ?
208
144
          heap_open_from_share(internal_share, mode) :
251
187
    with '\'-delimited path.
252
188
*/
253
189
 
254
 
Cursor *ha_heap::clone(memory::Root *mem_root)
 
190
handler *ha_heap::clone(MEM_ROOT *mem_root)
255
191
{
256
 
  Cursor *new_handler= table->s->db_type()->getCursor(*table->s, mem_root);
257
 
 
 
192
  handler *new_handler= get_new_handler(table->s, mem_root, table->s->db_type());
258
193
  if (new_handler && !new_handler->ha_open(table, file->s->name, table->db_stat,
259
194
                                           HA_OPEN_IGNORE_IF_LOCKED))
260
195
    return new_handler;
261
 
  return NULL;
 
196
  return NULL;  /* purecov: inspected */
262
197
}
263
198
 
264
199
 
269
204
}
270
205
 
271
206
 
 
207
uint32_t ha_heap::index_flags(uint32_t inx, uint32_t, bool) const
 
208
{
 
209
  return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
 
210
          HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE :
 
211
          HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
 
212
}
 
213
 
 
214
 
272
215
/*
273
216
  Compute which keys to use for scanning
274
217
 
326
269
int ha_heap::write_row(unsigned char * buf)
327
270
{
328
271
  int res;
329
 
  ha_statistic_increment(&system_status_var::ha_write_count);
 
272
  ha_statistic_increment(&SSV::ha_write_count);
330
273
  if (table->next_number_field && buf == table->record[0])
331
274
  {
332
275
    if ((res= update_auto_increment()))
333
276
      return res;
334
277
  }
335
278
  res= heap_write(file,buf);
336
 
  if (!res && (++records_changed*MEMORY_STATS_UPDATE_THRESHOLD >
 
279
  if (!res && (++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
337
280
               file->s->records))
338
281
  {
339
282
    /*
348
291
int ha_heap::update_row(const unsigned char * old_data, unsigned char * new_data)
349
292
{
350
293
  int res;
351
 
  ha_statistic_increment(&system_status_var::ha_update_count);
 
294
  ha_statistic_increment(&SSV::ha_update_count);
352
295
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
353
296
    table->timestamp_field->set_time();
354
297
  res= heap_update(file,old_data,new_data);
355
 
  if (!res && ++records_changed*MEMORY_STATS_UPDATE_THRESHOLD >
 
298
  if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
356
299
              file->s->records)
357
300
  {
358
301
    /*
367
310
int ha_heap::delete_row(const unsigned char * buf)
368
311
{
369
312
  int res;
370
 
  ha_statistic_increment(&system_status_var::ha_delete_count);
 
313
  ha_statistic_increment(&SSV::ha_delete_count);
371
314
  res= heap_delete(file,buf);
372
 
  if (!res && table->s->tmp_table == message::Table::STANDARD &&
373
 
      ++records_changed*MEMORY_STATS_UPDATE_THRESHOLD > file->s->records)
 
315
  if (!res && table->s->tmp_table == NO_TMP_TABLE &&
 
316
      ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
374
317
  {
375
318
    /*
376
319
       We can perform this safely since only one writer at the time is
386
329
                            enum ha_rkey_function find_flag)
387
330
{
388
331
  assert(inited==INDEX);
389
 
  ha_statistic_increment(&system_status_var::ha_read_key_count);
 
332
  ha_statistic_increment(&SSV::ha_read_key_count);
390
333
  int error = heap_rkey(file,buf,active_index, key, keypart_map, find_flag);
391
334
  table->status = error ? STATUS_NOT_FOUND : 0;
392
335
  return error;
396
339
                                 key_part_map keypart_map)
397
340
{
398
341
  assert(inited==INDEX);
399
 
  ha_statistic_increment(&system_status_var::ha_read_key_count);
 
342
  ha_statistic_increment(&SSV::ha_read_key_count);
400
343
  int error= heap_rkey(file, buf, active_index, key, keypart_map,
401
344
                       HA_READ_PREFIX_LAST);
402
345
  table->status= error ? STATUS_NOT_FOUND : 0;
407
350
                                key_part_map keypart_map,
408
351
                                enum ha_rkey_function find_flag)
409
352
{
410
 
  ha_statistic_increment(&system_status_var::ha_read_key_count);
 
353
  ha_statistic_increment(&SSV::ha_read_key_count);
411
354
  int error = heap_rkey(file, buf, index, key, keypart_map, find_flag);
412
355
  table->status = error ? STATUS_NOT_FOUND : 0;
413
356
  return error;
416
359
int ha_heap::index_next(unsigned char * buf)
417
360
{
418
361
  assert(inited==INDEX);
419
 
  ha_statistic_increment(&system_status_var::ha_read_next_count);
 
362
  ha_statistic_increment(&SSV::ha_read_next_count);
420
363
  int error=heap_rnext(file,buf);
421
364
  table->status=error ? STATUS_NOT_FOUND: 0;
422
365
  return error;
425
368
int ha_heap::index_prev(unsigned char * buf)
426
369
{
427
370
  assert(inited==INDEX);
428
 
  ha_statistic_increment(&system_status_var::ha_read_prev_count);
 
371
  ha_statistic_increment(&SSV::ha_read_prev_count);
429
372
  int error=heap_rprev(file,buf);
430
373
  table->status=error ? STATUS_NOT_FOUND: 0;
431
374
  return error;
434
377
int ha_heap::index_first(unsigned char * buf)
435
378
{
436
379
  assert(inited==INDEX);
437
 
  ha_statistic_increment(&system_status_var::ha_read_first_count);
 
380
  ha_statistic_increment(&SSV::ha_read_first_count);
438
381
  int error=heap_rfirst(file, buf, active_index);
439
382
  table->status=error ? STATUS_NOT_FOUND: 0;
440
383
  return error;
443
386
int ha_heap::index_last(unsigned char * buf)
444
387
{
445
388
  assert(inited==INDEX);
446
 
  ha_statistic_increment(&system_status_var::ha_read_last_count);
 
389
  ha_statistic_increment(&SSV::ha_read_last_count);
447
390
  int error=heap_rlast(file, buf, active_index);
448
391
  table->status=error ? STATUS_NOT_FOUND: 0;
449
392
  return error;
456
399
 
457
400
int ha_heap::rnd_next(unsigned char *buf)
458
401
{
459
 
  ha_statistic_increment(&system_status_var::ha_read_rnd_next_count);
 
402
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
460
403
  int error=heap_scan(file, buf);
461
404
  table->status=error ? STATUS_NOT_FOUND: 0;
462
405
  return error;
466
409
{
467
410
  int error;
468
411
  HEAP_PTR heap_position;
469
 
  ha_statistic_increment(&system_status_var::ha_read_rnd_count);
 
412
  ha_statistic_increment(&SSV::ha_read_rnd_count);
470
413
  memcpy(&heap_position, pos, sizeof(HEAP_PTR));
471
414
  error=heap_rrnd(file, buf, heap_position);
472
415
  table->status=error ? STATUS_NOT_FOUND: 0;
527
470
int ha_heap::delete_all_rows()
528
471
{
529
472
  heap_clear(file);
530
 
  if (table->s->tmp_table == message::Table::STANDARD)
 
473
  if (table->s->tmp_table == NO_TMP_TABLE)
531
474
  {
532
475
    /*
533
476
       We can perform this safely since only one writer at the time is
538
481
  return 0;
539
482
}
540
483
 
 
484
int ha_heap::external_lock(Session *, int)
 
485
{
 
486
  return 0;                                     // No external locking
 
487
}
 
488
 
 
489
 
541
490
/*
542
491
  Disable indexes.
543
492
 
596
545
    The indexes might have been disabled by disable_index() before.
597
546
    The function works only if both data and indexes are empty,
598
547
    since the heap storage engine cannot repair the indexes.
599
 
    To be sure, call Cursor::delete_all_rows() before.
 
548
    To be sure, call handler::delete_all_rows() before.
600
549
 
601
550
  IMPLEMENTATION
602
551
    HA_KEY_SWITCH_NONUNIQ       is not implemented.
645
594
  return heap_indexes_are_disabled(file);
646
595
}
647
596
 
 
597
THR_LOCK_DATA **ha_heap::store_lock(Session *,
 
598
                                    THR_LOCK_DATA **to,
 
599
                                    enum thr_lock_type lock_type)
 
600
{
 
601
  if (lock_type != TL_IGNORE && file->lock.type == TL_UNLOCK)
 
602
    file->lock.type=lock_type;
 
603
  *to++= &file->lock;
 
604
  return to;
 
605
}
 
606
 
648
607
void ha_heap::drop_table(const char *)
649
608
{
650
609
  file->s->delete_on_close= 1;
652
611
}
653
612
 
654
613
 
655
 
int HeapEngine::doRenameTable(Session &session, TableIdentifier &from, TableIdentifier &to)
 
614
int HeapEngine::renameTableImplementation(Session*,
 
615
                                          const char *from, const char *to)
656
616
{
657
 
  session.renameTableMessage(from, to);
658
 
  return heap_rename(from.getPath().c_str(), to.getPath().c_str());
 
617
  return heap_rename(from,to);
659
618
}
660
619
 
661
620
 
681
640
  return key->rec_per_key[key->key_parts-1];
682
641
}
683
642
 
684
 
int HeapEngine::doCreateTable(Session &session,
685
 
                              Table &table_arg,
686
 
                              drizzled::TableIdentifier &identifier,
687
 
                              message::Table& create_proto)
 
643
int HeapEngine::createTableImplementation(Session *session,
 
644
                                          const char *table_name,
 
645
                                          Table *table_arg,
 
646
                                          HA_CREATE_INFO *create_info,
 
647
                                          drizzled::message::Table*)
688
648
{
689
 
  int error;
690
649
  HP_SHARE *internal_share;
691
 
  const char *table_name= identifier.getPath().c_str();
692
 
 
693
 
  error= heap_create_table(&session, table_name, &table_arg,
694
 
                           false, 
695
 
                           create_proto,
696
 
                           &internal_share);
697
 
 
698
 
  if (error == 0)
699
 
  {
700
 
    session.storeTableMessage(identifier, create_proto);
701
 
  }
702
 
 
703
 
  return error;
 
650
  return heap_create_table(session, table_name, table_arg, create_info,
 
651
                           false, &internal_share);
704
652
}
705
653
 
706
654
 
707
655
int HeapEngine::heap_create_table(Session *session, const char *table_name,
708
 
                                  Table *table_arg,
709
 
                                  bool internal_table, 
710
 
                                  message::Table &create_proto,
711
 
                                  HP_SHARE **internal_share)
 
656
                             Table *table_arg, HA_CREATE_INFO *create_info,
 
657
                             bool internal_table, HP_SHARE **internal_share)
712
658
{
713
659
  uint32_t key, parts, mem_per_row_keys= 0, keys= table_arg->s->keys;
714
660
  uint32_t auto_key= 0, auto_key_type= 0;
722
668
  TableShare *share= table_arg->s;
723
669
  bool found_real_auto_increment= 0;
724
670
 
725
 
  /* 
726
 
   * We cannot create tables with more rows than UINT32_MAX.  This is a
727
 
   * limitation of the HEAP engine.  Here, since TableShare::getMaxRows()
728
 
   * can return a number more than that, we trap it here instead of casting
729
 
   * to a truncated integer.
730
 
   */
731
 
  uint64_t num_rows= share->getMaxRows();
732
 
  if (num_rows > UINT32_MAX)
733
 
    return -1;
734
 
 
735
671
  if (!(columndef= (HP_COLUMNDEF*) malloc(column_count * sizeof(HP_COLUMNDEF))))
736
 
    return errno;
 
672
    return my_errno;
737
673
 
738
674
  for (column_idx= 0; column_idx < column_count; column_idx++)
739
675
  {
771
707
                                    parts * sizeof(HA_KEYSEG))))
772
708
  {
773
709
    free((void *) columndef);
774
 
    return errno;
 
710
    return my_errno;
775
711
  }
776
712
 
777
713
  seg= reinterpret_cast<HA_KEYSEG*> (keydef + keys);
828
764
        key_part_size= next_field_pos;
829
765
      }
830
766
 
831
 
      if (field->flags & ENUM_FLAG)
 
767
      if (field->flags & (ENUM_FLAG | SET_FLAG))
832
768
        seg->charset= &my_charset_bin;
833
769
      else
834
770
        seg->charset= field->charset();
877
813
  HP_CREATE_INFO hp_create_info;
878
814
  hp_create_info.auto_key= auto_key;
879
815
  hp_create_info.auto_key_type= auto_key_type;
880
 
  hp_create_info.auto_increment= (create_proto.options().has_auto_increment_value() ?
881
 
                                  create_proto.options().auto_increment_value() - 1 : 0);
 
816
  hp_create_info.auto_increment= (create_info->auto_increment_value ?
 
817
                                  create_info->auto_increment_value - 1 : 0);
882
818
  hp_create_info.max_table_size=session->variables.max_heap_table_size;
883
819
  hp_create_info.with_auto_increment= found_real_auto_increment;
884
820
  hp_create_info.internal_table= internal_table;
885
821
  hp_create_info.max_chunk_size= share->block_size;
886
822
  hp_create_info.is_dynamic= (share->row_type == ROW_TYPE_DYNAMIC);
887
 
 
888
 
  error= heap_create(internal::fn_format(buff,table_name,"","",
889
 
                              MY_REPLACE_EXT|MY_UNPACK_FILENAME),
890
 
                    keys, keydef,
891
 
                    column_count, columndef,
892
 
                    max_key_fieldnr, key_part_size,
893
 
                    share->reclength, mem_per_row_keys,
894
 
                    static_cast<uint32_t>(num_rows), /* We check for overflow above, so cast is fine here. */
895
 
                    0, // Factor out MIN
896
 
                    &hp_create_info, internal_share);
 
823
  error= heap_create(fn_format(buff,table_name,"","",
 
824
                               MY_REPLACE_EXT|MY_UNPACK_FILENAME),
 
825
                   keys, keydef,
 
826
         column_count, columndef,
 
827
         max_key_fieldnr, key_part_size,
 
828
         share->reclength, mem_per_row_keys,
 
829
         (uint32_t) share->max_rows, (uint32_t) share->min_rows,
 
830
         &hp_create_info, internal_share);
897
831
 
898
832
  free((unsigned char*) keydef);
899
833
  free((void *) columndef);
902
836
}
903
837
 
904
838
 
 
839
void ha_heap::update_create_info(HA_CREATE_INFO *create_info)
 
840
{
 
841
  table->file->info(HA_STATUS_AUTO);
 
842
  if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
 
843
    create_info->auto_increment_value= stats.auto_increment_value;
 
844
  if (!(create_info->used_fields & HA_CREATE_USED_BLOCK_SIZE))
 
845
  {
 
846
    if (file->s->recordspace.is_variable_size)
 
847
      create_info->block_size= file->s->recordspace.chunk_length;
 
848
    else
 
849
      create_info->block_size= 0;
 
850
  }
 
851
}
 
852
 
905
853
void ha_heap::get_auto_increment(uint64_t, uint64_t, uint64_t,
906
854
                                 uint64_t *first_value,
907
855
                                 uint64_t *nb_reserved_values)
919
867
}
920
868
 
921
869
 
922
 
DRIZZLE_DECLARE_PLUGIN
 
870
drizzle_declare_plugin(heap)
923
871
{
924
 
  DRIZZLE_VERSION_ID,
925
872
  "MEMORY",
926
873
  "1.0",
927
874
  "MySQL AB",
928
875
  "Hash based, stored in memory, useful for temporary tables",
929
876
  PLUGIN_LICENSE_GPL,
930
877
  heap_init,
 
878
  heap_deinit,
 
879
  NULL,                       /* status variables                */
931
880
  NULL,                       /* system variables                */
932
881
  NULL                        /* config options                  */
933
882
}
934
 
DRIZZLE_DECLARE_PLUGIN_END;
 
883
drizzle_declare_plugin_end;