00001 /* Copyright (C) 2000,2004 MySQL AB & MySQL Finland AB & TCX DataKonsult AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 00018 #ifdef USE_PRAGMA_IMPLEMENTATION 00019 #pragma implementation // gcc: Class implementation 00020 #endif 00021 00022 #include "mysql_priv.h" 00023 #include <myisampack.h> 00024 #include "ha_heap.h" 00025 00026 00027 static handler *heap_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root); 00028 00029 handlerton heap_hton; 00030 00031 int heap_init() 00032 { 00033 heap_hton.state= SHOW_OPTION_YES; 00034 heap_hton.db_type= DB_TYPE_HEAP; 00035 heap_hton.create= heap_create_handler; 00036 heap_hton.panic= heap_panic; 00037 heap_hton.flags= HTON_CAN_RECREATE; 00038 return 0; 00039 } 00040 00041 static handler *heap_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root) 00042 { 00043 return new (mem_root) ha_heap(table); 00044 } 00045 00046 00047 /***************************************************************************** 00048 ** HEAP tables 00049 *****************************************************************************/ 00050 00051 ha_heap::ha_heap(TABLE_SHARE *table_arg) 00052 :handler(&heap_hton, table_arg), file(0), records_changed(0), 00053 key_stat_version(0) 00054 {} 00055 00056 00057 static const char *ha_heap_exts[] = { 00058 NullS 00059 }; 00060 00061 const char **ha_heap::bas_ext() const 00062 { 00063 return ha_heap_exts; 00064 } 00065 00066 /* 00067 Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to 00068 rec_per_key) after 1/HEAP_STATS_UPDATE_THRESHOLD fraction of table records 00069 have been inserted/updated/deleted. delete_all_rows() and table flush cause 00070 immediate update. 00071 00072 NOTE 00073 hash index statistics must be updated when number of table records changes 00074 from 0 to non-zero value and vice versa. Otherwise records_in_range may 00075 erroneously return 0 and 'range' may miss records. 00076 */ 00077 #define HEAP_STATS_UPDATE_THRESHOLD 10 00078 00079 int ha_heap::open(const char *name, int mode, uint test_if_locked) 00080 { 00081 if (!(file= heap_open(name, mode)) && my_errno == ENOENT) 00082 { 00083 HA_CREATE_INFO create_info; 00084 bzero(&create_info, sizeof(create_info)); 00085 if (!create(name, table, &create_info)) 00086 { 00087 file= heap_open(name, mode); 00088 implicit_emptied= 1; 00089 } 00090 } 00091 ref_length= sizeof(HEAP_PTR); 00092 if (file) 00093 { 00094 /* Initialize variables for the opened table */ 00095 set_keys_for_scanning(); 00096 /* 00097 We cannot run update_key_stats() here because we do not have a 00098 lock on the table. The 'records' count might just be changed 00099 temporarily at this moment and we might get wrong statistics (Bug 00100 #10178). Instead we request for update. This will be done in 00101 ha_heap::info(), which is always called before key statistics are 00102 used. 00103 */ 00104 key_stat_version= file->s->key_stat_version-1; 00105 } 00106 return (file ? 0 : 1); 00107 } 00108 00109 int ha_heap::close(void) 00110 { 00111 return heap_close(file); 00112 } 00113 00114 00115 /* 00116 Compute which keys to use for scanning 00117 00118 SYNOPSIS 00119 set_keys_for_scanning() 00120 no parameter 00121 00122 DESCRIPTION 00123 Set the bitmap btree_keys, which is used when the upper layers ask 00124 which keys to use for scanning. For each btree index the 00125 corresponding bit is set. 00126 00127 RETURN 00128 void 00129 */ 00130 00131 void ha_heap::set_keys_for_scanning(void) 00132 { 00133 btree_keys.clear_all(); 00134 for (uint i= 0 ; i < table->s->keys ; i++) 00135 { 00136 if (table->key_info[i].algorithm == HA_KEY_ALG_BTREE) 00137 btree_keys.set_bit(i); 00138 } 00139 } 00140 00141 00142 void ha_heap::update_key_stats() 00143 { 00144 for (uint i= 0; i < table->s->keys; i++) 00145 { 00146 KEY *key=table->key_info+i; 00147 if (!key->rec_per_key) 00148 continue; 00149 if (key->algorithm != HA_KEY_ALG_BTREE) 00150 { 00151 if (key->flags & HA_NOSAME) 00152 key->rec_per_key[key->key_parts-1]= 1; 00153 else 00154 { 00155 ha_rows hash_buckets= file->s->keydef[i].hash_buckets; 00156 uint no_records= hash_buckets ? file->s->records/hash_buckets : 2; 00157 if (no_records < 2) 00158 no_records= 2; 00159 key->rec_per_key[key->key_parts-1]= no_records; 00160 } 00161 } 00162 } 00163 records_changed= 0; 00164 /* At the end of update_key_stats() we can proudly claim they are OK. */ 00165 key_stat_version= file->s->key_stat_version; 00166 } 00167 00168 00169 int ha_heap::write_row(byte * buf) 00170 { 00171 int res; 00172 statistic_increment(table->in_use->status_var.ha_write_count,&LOCK_status); 00173 if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) 00174 table->timestamp_field->set_time(); 00175 if (table->next_number_field && buf == table->record[0]) 00176 update_auto_increment(); 00177 res= heap_write(file,buf); 00178 if (!res && (++records_changed*HEAP_STATS_UPDATE_THRESHOLD > 00179 file->s->records)) 00180 { 00181 /* 00182 We can perform this safely since only one writer at the time is 00183 allowed on the table. 00184 */ 00185 file->s->key_stat_version++; 00186 } 00187 return res; 00188 } 00189 00190 int ha_heap::update_row(const byte * old_data, byte * new_data) 00191 { 00192 int res; 00193 statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status); 00194 if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) 00195 table->timestamp_field->set_time(); 00196 res= heap_update(file,old_data,new_data); 00197 if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > 00198 file->s->records) 00199 { 00200 /* 00201 We can perform this safely since only one writer at the time is 00202 allowed on the table. 00203 */ 00204 file->s->key_stat_version++; 00205 } 00206 return res; 00207 } 00208 00209 int ha_heap::delete_row(const byte * buf) 00210 { 00211 int res; 00212 statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status); 00213 res= heap_delete(file,buf); 00214 if (!res && table->s->tmp_table == NO_TMP_TABLE && 00215 ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records) 00216 { 00217 /* 00218 We can perform this safely since only one writer at the time is 00219 allowed on the table. 00220 */ 00221 file->s->key_stat_version++; 00222 } 00223 return res; 00224 } 00225 00226 int ha_heap::index_read(byte * buf, const byte * key, uint key_len, 00227 enum ha_rkey_function find_flag) 00228 { 00229 DBUG_ASSERT(inited==INDEX); 00230 statistic_increment(table->in_use->status_var.ha_read_key_count, 00231 &LOCK_status); 00232 int error = heap_rkey(file,buf,active_index, key, key_len, find_flag); 00233 table->status = error ? STATUS_NOT_FOUND : 0; 00234 return error; 00235 } 00236 00237 int ha_heap::index_read_last(byte *buf, const byte *key, uint key_len) 00238 { 00239 DBUG_ASSERT(inited==INDEX); 00240 statistic_increment(table->in_use->status_var.ha_read_key_count, 00241 &LOCK_status); 00242 int error= heap_rkey(file, buf, active_index, key, key_len, 00243 HA_READ_PREFIX_LAST); 00244 table->status= error ? STATUS_NOT_FOUND : 0; 00245 return error; 00246 } 00247 00248 int ha_heap::index_read_idx(byte * buf, uint index, const byte * key, 00249 uint key_len, enum ha_rkey_function find_flag) 00250 { 00251 statistic_increment(table->in_use->status_var.ha_read_key_count, 00252 &LOCK_status); 00253 int error = heap_rkey(file, buf, index, key, key_len, find_flag); 00254 table->status = error ? STATUS_NOT_FOUND : 0; 00255 return error; 00256 } 00257 00258 int ha_heap::index_next(byte * buf) 00259 { 00260 DBUG_ASSERT(inited==INDEX); 00261 statistic_increment(table->in_use->status_var.ha_read_next_count, 00262 &LOCK_status); 00263 int error=heap_rnext(file,buf); 00264 table->status=error ? STATUS_NOT_FOUND: 0; 00265 return error; 00266 } 00267 00268 int ha_heap::index_prev(byte * buf) 00269 { 00270 DBUG_ASSERT(inited==INDEX); 00271 statistic_increment(table->in_use->status_var.ha_read_prev_count, 00272 &LOCK_status); 00273 int error=heap_rprev(file,buf); 00274 table->status=error ? STATUS_NOT_FOUND: 0; 00275 return error; 00276 } 00277 00278 int ha_heap::index_first(byte * buf) 00279 { 00280 DBUG_ASSERT(inited==INDEX); 00281 statistic_increment(table->in_use->status_var.ha_read_first_count, 00282 &LOCK_status); 00283 int error=heap_rfirst(file, buf, active_index); 00284 table->status=error ? STATUS_NOT_FOUND: 0; 00285 return error; 00286 } 00287 00288 int ha_heap::index_last(byte * buf) 00289 { 00290 DBUG_ASSERT(inited==INDEX); 00291 statistic_increment(table->in_use->status_var.ha_read_last_count, 00292 &LOCK_status); 00293 int error=heap_rlast(file, buf, active_index); 00294 table->status=error ? STATUS_NOT_FOUND: 0; 00295 return error; 00296 } 00297 00298 int ha_heap::rnd_init(bool scan) 00299 { 00300 return scan ? heap_scan_init(file) : 0; 00301 } 00302 00303 int ha_heap::rnd_next(byte *buf) 00304 { 00305 statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, 00306 &LOCK_status); 00307 int error=heap_scan(file, buf); 00308 table->status=error ? STATUS_NOT_FOUND: 0; 00309 return error; 00310 } 00311 00312 int ha_heap::rnd_pos(byte * buf, byte *pos) 00313 { 00314 int error; 00315 HEAP_PTR position; 00316 statistic_increment(table->in_use->status_var.ha_read_rnd_count, 00317 &LOCK_status); 00318 memcpy_fixed((char*) &position,pos,sizeof(HEAP_PTR)); 00319 error=heap_rrnd(file, buf, position); 00320 table->status=error ? STATUS_NOT_FOUND: 0; 00321 return error; 00322 } 00323 00324 void ha_heap::position(const byte *record) 00325 { 00326 *(HEAP_PTR*) ref= heap_position(file); // Ref is aligned 00327 } 00328 00329 void ha_heap::info(uint flag) 00330 { 00331 HEAPINFO info; 00332 (void) heap_info(file,&info,flag); 00333 00334 errkey= info.errkey; 00335 stats.records = info.records; 00336 stats.deleted = info.deleted; 00337 stats.mean_rec_length=info.reclength; 00338 stats.data_file_length=info.data_length; 00339 stats.index_file_length=info.index_length; 00340 stats.max_data_file_length= info.max_records* info.reclength; 00341 stats.delete_length= info.deleted * info.reclength; 00342 if (flag & HA_STATUS_AUTO) 00343 stats.auto_increment_value= info.auto_increment; 00344 /* 00345 If info() is called for the first time after open(), we will still 00346 have to update the key statistics. Hoping that a table lock is now 00347 in place. 00348 */ 00349 if (key_stat_version != file->s->key_stat_version) 00350 update_key_stats(); 00351 } 00352 00353 00354 int ha_heap::extra(enum ha_extra_function operation) 00355 { 00356 return heap_extra(file,operation); 00357 } 00358 00359 00360 int ha_heap::reset() 00361 { 00362 return heap_reset(file); 00363 } 00364 00365 00366 int ha_heap::delete_all_rows() 00367 { 00368 heap_clear(file); 00369 if (table->s->tmp_table == NO_TMP_TABLE) 00370 { 00371 /* 00372 We can perform this safely since only one writer at the time is 00373 allowed on the table. 00374 */ 00375 file->s->key_stat_version++; 00376 } 00377 return 0; 00378 } 00379 00380 int ha_heap::external_lock(THD *thd, int lock_type) 00381 { 00382 return 0; // No external locking 00383 } 00384 00385 00386 /* 00387 Disable indexes. 00388 00389 SYNOPSIS 00390 disable_indexes() 00391 mode mode of operation: 00392 HA_KEY_SWITCH_NONUNIQ disable all non-unique keys 00393 HA_KEY_SWITCH_ALL disable all keys 00394 HA_KEY_SWITCH_NONUNIQ_SAVE dis. non-uni. and make persistent 00395 HA_KEY_SWITCH_ALL_SAVE dis. all keys and make persistent 00396 00397 DESCRIPTION 00398 Disable indexes and clear keys to use for scanning. 00399 00400 IMPLEMENTATION 00401 HA_KEY_SWITCH_NONUNIQ is not implemented. 00402 HA_KEY_SWITCH_NONUNIQ_SAVE is not implemented with HEAP. 00403 HA_KEY_SWITCH_ALL_SAVE is not implemented with HEAP. 00404 00405 RETURN 00406 0 ok 00407 HA_ERR_WRONG_COMMAND mode not implemented. 00408 */ 00409 00410 int ha_heap::disable_indexes(uint mode) 00411 { 00412 int error; 00413 00414 if (mode == HA_KEY_SWITCH_ALL) 00415 { 00416 if (!(error= heap_disable_indexes(file))) 00417 set_keys_for_scanning(); 00418 } 00419 else 00420 { 00421 /* mode not implemented */ 00422 error= HA_ERR_WRONG_COMMAND; 00423 } 00424 return error; 00425 } 00426 00427 00428 /* 00429 Enable indexes. 00430 00431 SYNOPSIS 00432 enable_indexes() 00433 mode mode of operation: 00434 HA_KEY_SWITCH_NONUNIQ enable all non-unique keys 00435 HA_KEY_SWITCH_ALL enable all keys 00436 HA_KEY_SWITCH_NONUNIQ_SAVE en. non-uni. and make persistent 00437 HA_KEY_SWITCH_ALL_SAVE en. all keys and make persistent 00438 00439 DESCRIPTION 00440 Enable indexes and set keys to use for scanning. 00441 The indexes might have been disabled by disable_index() before. 00442 The function works only if both data and indexes are empty, 00443 since the heap storage engine cannot repair the indexes. 00444 To be sure, call handler::delete_all_rows() before. 00445 00446 IMPLEMENTATION 00447 HA_KEY_SWITCH_NONUNIQ is not implemented. 00448 HA_KEY_SWITCH_NONUNIQ_SAVE is not implemented with HEAP. 00449 HA_KEY_SWITCH_ALL_SAVE is not implemented with HEAP. 00450 00451 RETURN 00452 0 ok 00453 HA_ERR_CRASHED data or index is non-empty. Delete all rows and retry. 00454 HA_ERR_WRONG_COMMAND mode not implemented. 00455 */ 00456 00457 int ha_heap::enable_indexes(uint mode) 00458 { 00459 int error; 00460 00461 if (mode == HA_KEY_SWITCH_ALL) 00462 { 00463 if (!(error= heap_enable_indexes(file))) 00464 set_keys_for_scanning(); 00465 } 00466 else 00467 { 00468 /* mode not implemented */ 00469 error= HA_ERR_WRONG_COMMAND; 00470 } 00471 return error; 00472 } 00473 00474 00475 /* 00476 Test if indexes are disabled. 00477 00478 SYNOPSIS 00479 indexes_are_disabled() 00480 no parameters 00481 00482 RETURN 00483 0 indexes are not disabled 00484 1 all indexes are disabled 00485 [2 non-unique indexes are disabled - NOT YET IMPLEMENTED] 00486 */ 00487 00488 int ha_heap::indexes_are_disabled(void) 00489 { 00490 return heap_indexes_are_disabled(file); 00491 } 00492 00493 THR_LOCK_DATA **ha_heap::store_lock(THD *thd, 00494 THR_LOCK_DATA **to, 00495 enum thr_lock_type lock_type) 00496 { 00497 if (lock_type != TL_IGNORE && file->lock.type == TL_UNLOCK) 00498 file->lock.type=lock_type; 00499 *to++= &file->lock; 00500 return to; 00501 } 00502 00503 /* 00504 We have to ignore ENOENT entries as the HEAP table is created on open and 00505 not when doing a CREATE on the table. 00506 */ 00507 00508 int ha_heap::delete_table(const char *name) 00509 { 00510 int error= heap_delete_table(name); 00511 return error == ENOENT ? 0 : error; 00512 } 00513 00514 00515 void ha_heap::drop_table(const char *name) 00516 { 00517 heap_drop_table(file); 00518 close(); 00519 } 00520 00521 00522 int ha_heap::rename_table(const char * from, const char * to) 00523 { 00524 return heap_rename(from,to); 00525 } 00526 00527 00528 ha_rows ha_heap::records_in_range(uint inx, key_range *min_key, 00529 key_range *max_key) 00530 { 00531 KEY *key=table->key_info+inx; 00532 if (key->algorithm == HA_KEY_ALG_BTREE) 00533 return hp_rb_records_in_range(file, inx, min_key, max_key); 00534 00535 if (!min_key || !max_key || 00536 min_key->length != max_key->length || 00537 min_key->length != key->key_length || 00538 min_key->flag != HA_READ_KEY_EXACT || 00539 max_key->flag != HA_READ_AFTER_KEY) 00540 return HA_POS_ERROR; // Can only use exact keys 00541 00542 if (stats.records <= 1) 00543 return stats.records; 00544 00545 /* Assert that info() did run. We need current statistics here. */ 00546 DBUG_ASSERT(key_stat_version == file->s->key_stat_version); 00547 return key->rec_per_key[key->key_parts-1]; 00548 } 00549 00550 00551 int ha_heap::create(const char *name, TABLE *table_arg, 00552 HA_CREATE_INFO *create_info) 00553 { 00554 uint key, parts, mem_per_row= 0, keys= table_arg->s->keys; 00555 uint auto_key= 0, auto_key_type= 0; 00556 ha_rows max_rows; 00557 HP_KEYDEF *keydef; 00558 HA_KEYSEG *seg; 00559 int error; 00560 TABLE_SHARE *share= table_arg->s; 00561 bool found_real_auto_increment= 0; 00562 00563 for (key= parts= 0; key < keys; key++) 00564 parts+= table_arg->key_info[key].key_parts; 00565 00566 if (!(keydef= (HP_KEYDEF*) my_malloc(keys * sizeof(HP_KEYDEF) + 00567 parts * sizeof(HA_KEYSEG), 00568 MYF(MY_WME)))) 00569 return my_errno; 00570 seg= my_reinterpret_cast(HA_KEYSEG*) (keydef + keys); 00571 for (key= 0; key < keys; key++) 00572 { 00573 KEY *pos= table_arg->key_info+key; 00574 KEY_PART_INFO *key_part= pos->key_part; 00575 KEY_PART_INFO *key_part_end= key_part + pos->key_parts; 00576 00577 keydef[key].keysegs= (uint) pos->key_parts; 00578 keydef[key].flag= (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL)); 00579 keydef[key].seg= seg; 00580 00581 switch (pos->algorithm) { 00582 case HA_KEY_ALG_UNDEF: 00583 case HA_KEY_ALG_HASH: 00584 keydef[key].algorithm= HA_KEY_ALG_HASH; 00585 mem_per_row+= sizeof(char*) * 2; // = sizeof(HASH_INFO) 00586 break; 00587 case HA_KEY_ALG_BTREE: 00588 keydef[key].algorithm= HA_KEY_ALG_BTREE; 00589 mem_per_row+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*); 00590 break; 00591 default: 00592 DBUG_ASSERT(0); // cannot happen 00593 } 00594 00595 for (; key_part != key_part_end; key_part++, seg++) 00596 { 00597 Field *field= key_part->field; 00598 00599 if (pos->algorithm == HA_KEY_ALG_BTREE) 00600 seg->type= field->key_type(); 00601 else 00602 { 00603 if ((seg->type = field->key_type()) != (int) HA_KEYTYPE_TEXT && 00604 seg->type != HA_KEYTYPE_VARTEXT1 && 00605 seg->type != HA_KEYTYPE_VARTEXT2 && 00606 seg->type != HA_KEYTYPE_VARBINARY1 && 00607 seg->type != HA_KEYTYPE_VARBINARY2) 00608 seg->type= HA_KEYTYPE_BINARY; 00609 } 00610 seg->start= (uint) key_part->offset; 00611 seg->length= (uint) key_part->length; 00612 seg->flag= key_part->key_part_flag; 00613 00614 seg->charset= field->charset(); 00615 if (field->null_ptr) 00616 { 00617 seg->null_bit= field->null_bit; 00618 seg->null_pos= (uint) (field->null_ptr - (uchar*) table_arg->record[0]); 00619 } 00620 else 00621 { 00622 seg->null_bit= 0; 00623 seg->null_pos= 0; 00624 } 00625 if (field->flags & AUTO_INCREMENT_FLAG && 00626 table_arg->found_next_number_field && 00627 key == share->next_number_index) 00628 { 00629 /* 00630 Store key number and type for found auto_increment key 00631 We have to store type as seg->type can differ from it 00632 */ 00633 auto_key= key+ 1; 00634 auto_key_type= field->key_type(); 00635 } 00636 } 00637 } 00638 mem_per_row+= MY_ALIGN(share->reclength + 1, sizeof(char*)); 00639 max_rows = (ha_rows) (table_arg->in_use->variables.max_heap_table_size / 00640 mem_per_row); 00641 if (table_arg->found_next_number_field) 00642 { 00643 keydef[share->next_number_index].flag|= HA_AUTO_KEY; 00644 found_real_auto_increment= share->next_number_key_offset == 0; 00645 } 00646 HP_CREATE_INFO hp_create_info; 00647 hp_create_info.auto_key= auto_key; 00648 hp_create_info.auto_key_type= auto_key_type; 00649 hp_create_info.auto_increment= (create_info->auto_increment_value ? 00650 create_info->auto_increment_value - 1 : 0); 00651 hp_create_info.max_table_size=current_thd->variables.max_heap_table_size; 00652 hp_create_info.with_auto_increment= found_real_auto_increment; 00653 max_rows = (ha_rows) (hp_create_info.max_table_size / mem_per_row); 00654 error= heap_create(name, 00655 keys, keydef, share->reclength, 00656 (ulong) ((share->max_rows < max_rows && 00657 share->max_rows) ? 00658 share->max_rows : max_rows), 00659 (ulong) share->min_rows, &hp_create_info); 00660 my_free((gptr) keydef, MYF(0)); 00661 if (file) 00662 info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE); 00663 return (error); 00664 } 00665 00666 00667 void ha_heap::update_create_info(HA_CREATE_INFO *create_info) 00668 { 00669 table->file->info(HA_STATUS_AUTO); 00670 if (!(create_info->used_fields & HA_CREATE_USED_AUTO)) 00671 create_info->auto_increment_value= stats.auto_increment_value; 00672 } 00673 00674 void ha_heap::get_auto_increment(ulonglong offset, ulonglong increment, 00675 ulonglong nb_desired_values, 00676 ulonglong *first_value, 00677 ulonglong *nb_reserved_values) 00678 { 00679 ha_heap::info(HA_STATUS_AUTO); 00680 *first_value= stats.auto_increment_value; 00681 /* such table has only table-level locking so reserves up to +inf */ 00682 *nb_reserved_values= ULONGLONG_MAX; 00683 } 00684 00685 00686 bool ha_heap::check_if_incompatible_data(HA_CREATE_INFO *info, 00687 uint table_changes) 00688 { 00689 /* Check that auto_increment value was not changed */ 00690 if ((table_changes != IS_EQUAL_YES && 00691 info->used_fields & HA_CREATE_USED_AUTO) && 00692 info->auto_increment_value != 0) 00693 return COMPATIBLE_DATA_NO; 00694 return COMPATIBLE_DATA_YES; 00695 } 00696 00697 struct st_mysql_storage_engine heap_storage_engine= 00698 { MYSQL_HANDLERTON_INTERFACE_VERSION, &heap_hton}; 00699 00700 mysql_declare_plugin(heap) 00701 { 00702 MYSQL_STORAGE_ENGINE_PLUGIN, 00703 &heap_storage_engine, 00704 "MEMORY", 00705 "MySQL AB", 00706 "Hash based, stored in memory, useful for temporary tables", 00707 heap_init, 00708 NULL, 00709 0x0100, /* 1.0 */ 00710 0 00711 } 00712 mysql_declare_plugin_end;
1.4.7

