12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16
#include "heap_priv.h"
17
#include <drizzled/error.h>
18
#include <drizzled/table.h>
19
#include <drizzled/session.h>
20
#include <drizzled/field/varstring.h>
21
#include <drizzled/plugin/daemon.h>
22
#include <drizzled/plugin/storage_engine.h>
24
#include <boost/thread/mutex.hpp>
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#define DRIZZLE_SERVER 1
17
#include <drizzled/server_includes.h>
27
18
#include "ha_heap.h"
32
using namespace drizzled;
35
static const string engine_name("MEMORY");
37
boost::mutex THR_LOCK_heap;
39
static const char *ha_heap_exts[] = {
43
class HeapEngine : public plugin::StorageEngine
46
explicit HeapEngine(string name_arg) :
47
plugin::StorageEngine(name_arg,
48
HTON_STATS_RECORDS_IS_EXACT |
53
HTON_SKIP_STORE_LOCK |
60
hp_panic(HA_PANIC_CLOSE);
63
virtual Cursor *create(Table &table)
65
return new ha_heap(*this, table);
68
const char **bas_ext() const {
72
int doCreateTable(Session &session,
74
const identifier::Table &identifier,
75
message::Table &create_proto);
77
/* For whatever reason, internal tables can be created by Cursor::open()
79
Instead of diving down a rat hole, let's just cry ourselves to sleep
80
at night with this odd hackish workaround.
82
int heap_create_table(Session *session, const char *table_name,
85
message::Table &create_proto,
86
HP_SHARE **internal_share);
88
int doRenameTable(Session&, const identifier::Table &from, const identifier::Table &to);
90
int doDropTable(Session&, const identifier::Table &identifier);
92
int doGetTableDefinition(Session& session,
93
const identifier::Table &identifier,
94
message::Table &table_message);
96
uint32_t max_supported_keys() const { return MAX_KEY; }
97
uint32_t max_supported_key_part_length() const { return MAX_KEY_LENGTH; }
99
uint32_t index_flags(enum ha_key_alg ) const
101
return ( HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
104
bool doDoesTableExist(Session& session, const identifier::Table &identifier);
105
void doGetTableIdentifiers(CachedDirectory &directory,
106
const identifier::Schema &schema_identifier,
107
identifier::Table::vector &set_of_identifiers);
110
void HeapEngine::doGetTableIdentifiers(CachedDirectory&,
111
const identifier::Schema&,
112
identifier::Table::vector&)
116
bool HeapEngine::doDoesTableExist(Session& session, const identifier::Table &identifier)
118
return session.getMessageCache().doesTableMessageExist(identifier);
121
int HeapEngine::doGetTableDefinition(Session &session,
122
const identifier::Table &identifier,
123
message::Table &table_proto)
125
if (session.getMessageCache().getTableMessage(identifier, table_proto))
131
We have to ignore ENOENT entries as the MEMORY table is created on open and
132
not when doing a CREATE on the table.
134
int HeapEngine::doDropTable(Session &session, const identifier::Table &identifier)
136
session.getMessageCache().removeTableMessage(identifier);
138
int error= heap_delete_table(identifier.getPath().c_str());
146
static HeapEngine *heap_storage_engine= NULL;
148
static int heap_init(module::Context &context)
150
heap_storage_engine= new HeapEngine(engine_name);
151
context.add(heap_storage_engine);
21
static handler *heap_create_handler(handlerton *hton,
25
int heap_deinit(void *p __attribute__((unused)))
28
return hp_panic(HA_PANIC_CLOSE);
32
int heap_init(void *p)
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;
44
static handler *heap_create_handler(handlerton *hton,
48
return new (mem_root) ha_heap(hton, table);
156
52
/*****************************************************************************
158
54
*****************************************************************************/
160
ha_heap::ha_heap(plugin::StorageEngine &engine_arg,
162
:Cursor(engine_arg, table_arg), file(0), records_changed(0), key_stat_version(0),
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),
62
static const char *ha_heap_exts[] = {
66
const char **ha_heap::bas_ext() const
167
Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to
168
rec_per_key) after 1/MEMORY_STATS_UPDATE_THRESHOLD fraction of table records
169
have been inserted/updated/deleted. delete_all_rows() and table flush cause
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
173
78
hash index statistics must be updated when number of table records changes
174
from 0 to non-zero value and vice versa. Otherwise records_in_range may
79
from 0 to non-zero value and vice versa. Otherwise records_in_range may
175
80
erroneously return 0 and 'range' may miss records.
177
#define MEMORY_STATS_UPDATE_THRESHOLD 10
82
#define HEAP_STATS_UPDATE_THRESHOLD 10
179
int ha_heap::doOpen(const drizzled::identifier::Table &identifier, int mode, uint32_t test_if_locked)
84
int ha_heap::open(const char *name, int mode, uint test_if_locked)
181
if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(identifier.getPath().c_str(), mode)) && errno == ENOENT))
86
if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(name, mode)) && my_errno == ENOENT))
88
HA_CREATE_INFO create_info;
183
89
internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
90
memset(&create_info, 0, sizeof(create_info));
185
HP_SHARE *internal_share= NULL;
186
message::Table create_proto;
188
if (not heap_storage_engine->heap_create_table(getTable()->in_use,
189
identifier.getPath().c_str(),
92
if (!create(name, table, &create_info))
195
94
file= internal_table ?
196
95
heap_open_from_share(internal_share, mode) :
304
199
records_changed= 0;
305
200
/* At the end of update_key_stats() we can proudly claim they are OK. */
306
key_stat_version= file->getShare()->key_stat_version;
201
key_stat_version= file->s->key_stat_version;
310
int ha_heap::doInsertRecord(unsigned char * buf)
205
int ha_heap::write_row(uchar * buf)
313
if (getTable()->next_number_field && buf == getTable()->getInsertRecord())
208
ha_statistic_increment(&SSV::ha_write_count);
209
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
210
table->timestamp_field->set_time();
211
if (table->next_number_field && buf == table->record[0])
315
213
if ((res= update_auto_increment()))
318
216
res= heap_write(file,buf);
319
if (!res && (++records_changed*MEMORY_STATS_UPDATE_THRESHOLD >
320
file->getShare()->records))
217
if (!res && (++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
323
221
We can perform this safely since only one writer at the time is
324
222
allowed on the table.
326
file->getShare()->key_stat_version++;
224
file->s->key_stat_version++;
331
int ha_heap::doUpdateRecord(const unsigned char * old_data, unsigned char * new_data)
229
int ha_heap::update_row(const uchar * old_data, uchar * new_data)
232
ha_statistic_increment(&SSV::ha_update_count);
233
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
234
table->timestamp_field->set_time();
335
235
res= heap_update(file,old_data,new_data);
336
if (!res && ++records_changed*MEMORY_STATS_UPDATE_THRESHOLD >
337
file->getShare()->records)
236
if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
340
240
We can perform this safely since only one writer at the time is
341
241
allowed on the table.
343
file->getShare()->key_stat_version++;
243
file->s->key_stat_version++;
348
int ha_heap::doDeleteRecord(const unsigned char * buf)
248
int ha_heap::delete_row(const uchar * buf)
251
ha_statistic_increment(&SSV::ha_delete_count);
352
252
res= heap_delete(file,buf);
353
if (!res && getTable()->getShare()->getType() == message::Table::STANDARD &&
354
++records_changed*MEMORY_STATS_UPDATE_THRESHOLD > file->getShare()->records)
253
if (!res && table->s->tmp_table == NO_TMP_TABLE &&
254
++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
357
257
We can perform this safely since only one writer at the time is
358
258
allowed on the table.
360
file->getShare()->key_stat_version++;
260
file->s->key_stat_version++;
365
int ha_heap::index_read_map(unsigned char *buf, const unsigned char *key,
265
int ha_heap::index_read_map(uchar *buf, const uchar *key,
366
266
key_part_map keypart_map,
367
267
enum ha_rkey_function find_flag)
369
269
assert(inited==INDEX);
370
ha_statistic_increment(&system_status_var::ha_read_key_count);
270
ha_statistic_increment(&SSV::ha_read_key_count);
371
271
int error = heap_rkey(file,buf,active_index, key, keypart_map, find_flag);
372
getTable()->status = error ? STATUS_NOT_FOUND : 0;
272
table->status = error ? STATUS_NOT_FOUND : 0;
376
int ha_heap::index_read_last_map(unsigned char *buf, const unsigned char *key,
276
int ha_heap::index_read_last_map(uchar *buf, const uchar *key,
377
277
key_part_map keypart_map)
379
279
assert(inited==INDEX);
380
ha_statistic_increment(&system_status_var::ha_read_key_count);
280
ha_statistic_increment(&SSV::ha_read_key_count);
381
281
int error= heap_rkey(file, buf, active_index, key, keypart_map,
382
282
HA_READ_PREFIX_LAST);
383
getTable()->status= error ? STATUS_NOT_FOUND : 0;
283
table->status= error ? STATUS_NOT_FOUND : 0;
387
int ha_heap::index_read_idx_map(unsigned char *buf, uint32_t index, const unsigned char *key,
287
int ha_heap::index_read_idx_map(uchar *buf, uint index, const uchar *key,
388
288
key_part_map keypart_map,
389
289
enum ha_rkey_function find_flag)
391
ha_statistic_increment(&system_status_var::ha_read_key_count);
291
ha_statistic_increment(&SSV::ha_read_key_count);
392
292
int error = heap_rkey(file, buf, index, key, keypart_map, find_flag);
393
getTable()->status = error ? STATUS_NOT_FOUND : 0;
293
table->status = error ? STATUS_NOT_FOUND : 0;
397
int ha_heap::index_next(unsigned char * buf)
297
int ha_heap::index_next(uchar * buf)
399
299
assert(inited==INDEX);
400
ha_statistic_increment(&system_status_var::ha_read_next_count);
300
ha_statistic_increment(&SSV::ha_read_next_count);
401
301
int error=heap_rnext(file,buf);
402
getTable()->status=error ? STATUS_NOT_FOUND: 0;
302
table->status=error ? STATUS_NOT_FOUND: 0;
406
int ha_heap::index_prev(unsigned char * buf)
306
int ha_heap::index_prev(uchar * buf)
408
308
assert(inited==INDEX);
409
ha_statistic_increment(&system_status_var::ha_read_prev_count);
309
ha_statistic_increment(&SSV::ha_read_prev_count);
410
310
int error=heap_rprev(file,buf);
411
getTable()->status=error ? STATUS_NOT_FOUND: 0;
311
table->status=error ? STATUS_NOT_FOUND: 0;
415
int ha_heap::index_first(unsigned char * buf)
315
int ha_heap::index_first(uchar * buf)
417
317
assert(inited==INDEX);
418
ha_statistic_increment(&system_status_var::ha_read_first_count);
318
ha_statistic_increment(&SSV::ha_read_first_count);
419
319
int error=heap_rfirst(file, buf, active_index);
420
getTable()->status=error ? STATUS_NOT_FOUND: 0;
320
table->status=error ? STATUS_NOT_FOUND: 0;
424
int ha_heap::index_last(unsigned char * buf)
324
int ha_heap::index_last(uchar * buf)
426
326
assert(inited==INDEX);
427
ha_statistic_increment(&system_status_var::ha_read_last_count);
327
ha_statistic_increment(&SSV::ha_read_last_count);
428
328
int error=heap_rlast(file, buf, active_index);
429
getTable()->status=error ? STATUS_NOT_FOUND: 0;
329
table->status=error ? STATUS_NOT_FOUND: 0;
433
int ha_heap::doStartTableScan(bool scan)
333
int ha_heap::rnd_init(bool scan)
435
335
return scan ? heap_scan_init(file) : 0;
438
int ha_heap::rnd_next(unsigned char *buf)
338
int ha_heap::rnd_next(uchar *buf)
440
ha_statistic_increment(&system_status_var::ha_read_rnd_next_count);
340
ha_statistic_increment(&SSV::ha_read_rnd_next_count);
441
341
int error=heap_scan(file, buf);
442
getTable()->status=error ? STATUS_NOT_FOUND: 0;
342
table->status=error ? STATUS_NOT_FOUND: 0;
446
int ha_heap::rnd_pos(unsigned char * buf, unsigned char *pos)
346
int ha_heap::rnd_pos(uchar * buf, uchar *pos)
449
349
HEAP_PTR heap_position;
450
ha_statistic_increment(&system_status_var::ha_read_rnd_count);
350
ha_statistic_increment(&SSV::ha_read_rnd_count);
451
351
memcpy(&heap_position, pos, sizeof(HEAP_PTR));
452
352
error=heap_rrnd(file, buf, heap_position);
453
getTable()->status=error ? STATUS_NOT_FOUND: 0;
353
table->status=error ? STATUS_NOT_FOUND: 0;
457
void ha_heap::position(const unsigned char *)
357
void ha_heap::position(const uchar *record __attribute__((unused)))
459
359
*(HEAP_PTR*) ref= heap_position(file); // Ref is aligned
462
int ha_heap::info(uint32_t flag)
362
int ha_heap::info(uint flag)
464
364
HEAPINFO hp_info;
465
365
(void) heap_info(file,&hp_info,flag);
617
533
return heap_indexes_are_disabled(file);
620
void ha_heap::drop_table(const char *)
622
file->getShare()->delete_on_close= 1;
536
THR_LOCK_DATA **ha_heap::store_lock(THD *thd __attribute__((unused)),
538
enum thr_lock_type lock_type)
540
if (lock_type != TL_IGNORE && file->lock.type == TL_UNLOCK)
541
file->lock.type=lock_type;
547
We have to ignore ENOENT entries as the HEAP table is created on open and
548
not when doing a CREATE on the table.
551
int ha_heap::delete_table(const char *name)
553
int error= heap_delete_table(name);
554
return error == ENOENT ? 0 : error;
558
void ha_heap::drop_table(const char *name __attribute__((unused)))
560
file->s->delete_on_close= 1;
627
int HeapEngine::doRenameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
565
int ha_heap::rename_table(const char * from, const char * to)
629
session.getMessageCache().renameTableMessage(from, to);
630
return heap_rename(from.getPath().c_str(), to.getPath().c_str());
567
return heap_rename(from,to);
634
ha_rows ha_heap::records_in_range(uint32_t inx, key_range *min_key,
571
ha_rows ha_heap::records_in_range(uint inx, key_range *min_key,
635
572
key_range *max_key)
637
KeyInfo *key= &getTable()->key_info[inx];
574
KEY *key=table->key_info+inx;
575
if (key->algorithm == HA_KEY_ALG_BTREE)
576
return hp_rb_records_in_range(file, inx, min_key, max_key);
639
578
if (!min_key || !max_key ||
640
579
min_key->length != max_key->length ||
647
586
return stats.records;
649
588
/* Assert that info() did run. We need current statistics here. */
650
assert(key_stat_version == file->getShare()->key_stat_version);
589
assert(key_stat_version == file->s->key_stat_version);
651
590
return key->rec_per_key[key->key_parts-1];
654
int HeapEngine::doCreateTable(Session &session,
656
const identifier::Table &identifier,
657
message::Table& create_proto)
660
HP_SHARE *internal_share;
661
const char *table_name= identifier.getPath().c_str();
663
error= heap_create_table(&session, table_name, &table_arg,
670
session.getMessageCache().storeTableMessage(identifier, create_proto);
677
int HeapEngine::heap_create_table(Session *session, const char *table_name,
680
message::Table &create_proto,
681
HP_SHARE **internal_share)
683
uint32_t key, parts, mem_per_row_keys= 0;
684
uint32_t keys= table_arg->getShare()->sizeKeys();
685
uint32_t auto_key= 0, auto_key_type= 0;
686
uint32_t max_key_fieldnr = 0, key_part_size = 0, next_field_pos = 0;
687
uint32_t column_count= table_arg->getShare()->sizeFields();
688
std::vector<HP_KEYDEF> keydef;
594
int ha_heap::create(const char *name, Table *table_arg,
595
HA_CREATE_INFO *create_info)
597
uint key, parts, mem_per_row_keys= 0, keys= table_arg->s->keys;
598
uint auto_key= 0, auto_key_type= 0;
599
uint max_key_fieldnr = 0, key_part_size = 0, next_field_pos = 0;
600
uint column_idx, column_count= table_arg->s->fields;
601
HP_COLUMNDEF *columndef;
604
char buff[FN_REFLEN];
606
TABLE_SHARE *share= table_arg->s;
690
607
bool found_real_auto_increment= 0;
693
* We cannot create tables with more rows than UINT32_MAX. This is a
694
* limitation of the HEAP engine. Here, since TableShare::getMaxRows()
695
* can return a number more than that, we trap it here instead of casting
696
* to a truncated integer.
698
uint64_t num_rows= table_arg->getShare()->getMaxRows();
699
if (num_rows > UINT32_MAX)
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 - (uchar*) 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;
702
641
for (key= parts= 0; key < keys; key++)
703
642
parts+= table_arg->key_info[key].key_parts;
706
std::vector<HA_KEYSEG> seg_buffer;
707
seg_buffer.resize(parts);
708
HA_KEYSEG *seg= &seg_buffer[0];
644
if (!(keydef= (HP_KEYDEF*) my_malloc(keys * sizeof(HP_KEYDEF) +
645
parts * sizeof(HA_KEYSEG),
648
my_free((void *) columndef, MYF(0));
652
seg= my_reinterpret_cast(HA_KEYSEG*) (keydef + keys);
710
653
for (key= 0; key < keys; key++)
712
KeyInfo *pos= &table_arg->key_info[key];
713
KeyPartInfo *key_part= pos->key_part;
714
KeyPartInfo *key_part_end= key_part + pos->key_parts;
655
KEY *pos= table_arg->key_info+key;
656
KEY_PART_INFO *key_part= pos->key_part;
657
KEY_PART_INFO *key_part_end= key_part + pos->key_parts;
716
659
keydef[key].keysegs= (uint) pos->key_parts;
717
660
keydef[key].flag= (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL));
718
661
keydef[key].seg= seg;
720
mem_per_row_keys+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
663
switch (pos->algorithm) {
664
case HA_KEY_ALG_UNDEF:
665
case HA_KEY_ALG_HASH:
666
keydef[key].algorithm= HA_KEY_ALG_HASH;
667
mem_per_row_keys+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
669
case HA_KEY_ALG_BTREE:
670
keydef[key].algorithm= HA_KEY_ALG_BTREE;
671
mem_per_row_keys+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*);
674
assert(0); // cannot happen
722
677
for (; key_part != key_part_end; key_part++, seg++)
724
679
Field *field= key_part->field;
681
if (pos->algorithm == HA_KEY_ALG_BTREE)
682
seg->type= field->key_type();
727
685
if ((seg->type = field->key_type()) != (int) HA_KEYTYPE_TEXT &&
728
686
seg->type != HA_KEYTYPE_VARTEXT1 &&
770
728
auto_key= key+ 1;
771
729
auto_key_type= field->key_type();
773
if ((uint)field->position() + 1 > max_key_fieldnr)
731
if ((uint)field->field_index + 1 > max_key_fieldnr)
775
733
/* Do not use seg->fieldnr as it's not reliable in case of temp tables */
776
max_key_fieldnr= field->position() + 1;
734
max_key_fieldnr= field->field_index + 1;
781
if (key_part_size < table_arg->getShare()->null_bytes + ((table_arg->getShare()->last_null_bit_pos+7) >> 3))
739
if (key_part_size < share->null_bytes + ((share->last_null_bit_pos+7) >> 3))
783
741
/* Make sure to include null fields regardless of the presense of keys */
784
key_part_size = table_arg->getShare()->null_bytes + ((table_arg->getShare()->last_null_bit_pos+7) >> 3);
742
key_part_size = share->null_bytes + ((share->last_null_bit_pos+7) >> 3);
789
747
if (table_arg->found_next_number_field)
791
keydef[table_arg->getShare()->next_number_index].flag|= HA_AUTO_KEY;
792
found_real_auto_increment= table_arg->getShare()->next_number_key_offset == 0;
749
keydef[share->next_number_index].flag|= HA_AUTO_KEY;
750
found_real_auto_increment= share->next_number_key_offset == 0;
794
752
HP_CREATE_INFO hp_create_info;
795
753
hp_create_info.auto_key= auto_key;
796
754
hp_create_info.auto_key_type= auto_key_type;
797
hp_create_info.auto_increment= (create_proto.options().has_auto_increment_value() ?
798
create_proto.options().auto_increment_value() - 1 : 0);
799
hp_create_info.max_table_size=session->variables.max_heap_table_size;
755
hp_create_info.auto_increment= (create_info->auto_increment_value ?
756
create_info->auto_increment_value - 1 : 0);
757
hp_create_info.max_table_size=current_thd->variables.max_heap_table_size;
800
758
hp_create_info.with_auto_increment= found_real_auto_increment;
801
759
hp_create_info.internal_table= internal_table;
802
hp_create_info.max_chunk_size= table_arg->getShare()->block_size;
804
error= heap_create(table_name,
808
table_arg->getShare()->getRecordLength(), mem_per_row_keys,
809
static_cast<uint32_t>(num_rows), /* We check for overflow above, so cast is fine here. */
811
&hp_create_info, internal_share);
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
my_free((uchar*) keydef, MYF(0));
772
my_free((void *) columndef, MYF(0));
817
void ha_heap::get_auto_increment(uint64_t, uint64_t, uint64_t,
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)),
818
795
uint64_t *first_value,
819
796
uint64_t *nb_reserved_values)