diff options
Diffstat (limited to 'sql/ha_heap.cc')
-rw-r--r-- | sql/ha_heap.cc | 220 |
1 files changed, 133 insertions, 87 deletions
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index e6d7871b016..6cfd3c881cc 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -33,69 +33,14 @@ const char **ha_heap::bas_ext() const int ha_heap::open(const char *name, int mode, uint test_if_locked) { - uint key,parts,mem_per_row=0; - ulong max_rows; - HP_KEYDEF *keydef; - HP_KEYSEG *seg; - THD *thd= current_thd; - - for (key=parts=0 ; key < table->keys ; key++) - parts+=table->key_info[key].key_parts; - - if (!(keydef=(HP_KEYDEF*) my_malloc(table->keys*sizeof(HP_KEYDEF)+ - parts*sizeof(HP_KEYSEG),MYF(MY_WME)))) - return my_errno; - seg=my_reinterpret_cast(HP_KEYSEG*) (keydef+table->keys); - for (key=0 ; key < table->keys ; key++) + if (!(file= heap_open(name, mode)) && my_errno == ENOENT) { - KEY *pos=table->key_info+key; - KEY_PART_INFO *key_part= pos->key_part; - KEY_PART_INFO *key_part_end= key_part+pos->key_parts; - - mem_per_row += (pos->key_length + (sizeof(char*) * 2)); - - keydef[key].keysegs=(uint) pos->key_parts; - keydef[key].flag = (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL)); - keydef[key].seg=seg; - - for (; key_part != key_part_end ; key_part++, seg++) - { - uint flag=key_part->key_type; - Field *field=key_part->field; - if (!f_is_packed(flag) && - f_packtype(flag) == (int) FIELD_TYPE_DECIMAL && - !(flag & FIELDFLAG_BINARY)) - seg->type= (int) HA_KEYTYPE_TEXT; - else - seg->type= (int) HA_KEYTYPE_BINARY; - seg->start=(uint) key_part->offset; - seg->length=(uint) key_part->length; - if (field->null_ptr) - { - seg->null_bit=field->null_bit; - seg->null_pos= (uint) (field->null_ptr- - (uchar*) table->record[0]); - } - else - { - seg->null_bit=0; - seg->null_pos=0; - } - } + HA_CREATE_INFO create_info; + bzero(&create_info, sizeof(create_info)); + if (!create(name, table, &create_info)) + file= heap_open(name, mode); } - mem_per_row += MY_ALIGN(table->reclength+1, sizeof(char*)); - max_rows = (ulong) (thd->variables.max_heap_table_size / mem_per_row); - file=heap_open(name,mode, - table->keys,keydef, - table->reclength, - ((table->max_rows < max_rows && table->max_rows) ? - table->max_rows : max_rows), - table->min_rows); - my_free((gptr) keydef,MYF(0)); - if (file) - info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE); - ref_length=sizeof(HEAP_PTR); - return (!file ? errno : 0); + return (file ? 0 : 1); } int ha_heap::close(void) @@ -108,6 +53,8 @@ int ha_heap::write_row(byte * buf) statistic_increment(ha_write_count,&LOCK_status); if (table->time_stamp) update_timestamp(buf+table->time_stamp-1); + if (table->next_number_field && buf == table->record[0]) + update_auto_increment(); return heap_write(file,buf); } @@ -125,25 +72,21 @@ int ha_heap::delete_row(const byte * buf) return heap_delete(file,buf); } -int ha_heap::index_read(byte * buf, const byte * key, - uint key_len __attribute__((unused)), - enum ha_rkey_function find_flag - __attribute__((unused))) +int ha_heap::index_read(byte * buf, const byte * key, uint key_len, + enum ha_rkey_function find_flag) { - statistic_increment(ha_read_key_count,&LOCK_status); - int error=heap_rkey(file,buf,active_index, key); - table->status=error ? STATUS_NOT_FOUND: 0; + statistic_increment(ha_read_key_count, &LOCK_status); + int error = heap_rkey(file,buf,active_index, key, key_len, find_flag); + table->status = error ? STATUS_NOT_FOUND : 0; return error; } int ha_heap::index_read_idx(byte * buf, uint index, const byte * key, - uint key_len __attribute__((unused)), - enum ha_rkey_function find_flag - __attribute__((unused))) + uint key_len, enum ha_rkey_function find_flag) { - statistic_increment(ha_read_key_count,&LOCK_status); - int error=heap_rkey(file, buf, index, key); - table->status=error ? STATUS_NOT_FOUND: 0; + statistic_increment(ha_read_key_count, &LOCK_status); + int error = heap_rkey(file, buf, index, key, key_len, find_flag); + table->status = error ? STATUS_NOT_FOUND : 0; return error; } @@ -167,7 +110,7 @@ int ha_heap::index_prev(byte * buf) int ha_heap::index_first(byte * buf) { statistic_increment(ha_read_first_count,&LOCK_status); - int error=heap_rfirst(file, buf); + int error=heap_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; } @@ -175,7 +118,7 @@ int ha_heap::index_first(byte * buf) int ha_heap::index_last(byte * buf) { statistic_increment(ha_read_last_count,&LOCK_status); - int error=heap_rlast(file, buf); + int error=heap_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; } @@ -222,6 +165,8 @@ void ha_heap::info(uint flag) index_file_length=info.index_length; max_data_file_length= info.max_records* info.reclength; delete_length= info.deleted * info.reclength; + if (flag & HA_STATUS_AUTO) + auto_increment_value= info.auto_increment; } int ha_heap::extra(enum ha_extra_function operation) @@ -255,7 +200,6 @@ THR_LOCK_DATA **ha_heap::store_lock(THD *thd, return to; } - /* We have to ignore ENOENT entries as the HEAP table is created on open and not when doing a CREATE on the table. @@ -272,7 +216,6 @@ int ha_heap::rename_table(const char * from, const char * to) return heap_rename(from,to); } - ha_rows ha_heap::records_in_range(int inx, const byte *start_key,uint start_key_len, enum ha_rkey_function start_search_flag, @@ -280,18 +223,121 @@ ha_rows ha_heap::records_in_range(int inx, enum ha_rkey_function end_search_flag) { KEY *pos=table->key_info+inx; - if (start_key_len != end_key_len || - start_key_len != pos->key_length || - start_search_flag != HA_READ_KEY_EXACT || - end_search_flag != HA_READ_AFTER_KEY) - return HA_POS_ERROR; // Can't only use exact keys - return 10; // Good guess + if (pos->algorithm == HA_KEY_ALG_BTREE) + { + return hp_rb_records_in_range(file, inx, start_key, start_key_len, + start_search_flag, end_key, end_key_len, + end_search_flag); + } + else + { + if (start_key_len != end_key_len || + start_key_len != pos->key_length || + start_search_flag != HA_READ_KEY_EXACT || + end_search_flag != HA_READ_AFTER_KEY) + return HA_POS_ERROR; // Can't only use exact keys + return 10; // Good guess + } } +int ha_heap::create(const char *name, TABLE *table, + HA_CREATE_INFO *create_info) +{ + uint key, parts, mem_per_row= 0; + uint auto_key= 0, auto_key_type= 0; + ulong max_rows; + HP_KEYDEF *keydef; + HA_KEYSEG *seg; + char buff[FN_REFLEN]; + int error; + + for (key= parts= 0; key < table->keys; key++) + parts+= table->key_info[key].key_parts; + + if (!(keydef= (HP_KEYDEF*) my_malloc(table->keys * sizeof(HP_KEYDEF) + + parts * sizeof(HA_KEYSEG), + MYF(MY_WME)))) + return my_errno; + seg= my_reinterpret_cast(HA_KEYSEG*) (keydef + table->keys); + for (key= 0; key < table->keys; key++) + { + KEY *pos= table->key_info+key; + KEY_PART_INFO *key_part= pos->key_part; + KEY_PART_INFO *key_part_end= key_part + pos->key_parts; + + mem_per_row+= (pos->key_length + (sizeof(char*) * 2)); + + keydef[key].keysegs= (uint) pos->key_parts; + keydef[key].flag= (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL)); + keydef[key].seg= seg; + keydef[key].algorithm= ((pos->algorithm == HA_KEY_ALG_UNDEF) ? + HA_KEY_ALG_HASH : pos->algorithm); + + for (; key_part != key_part_end; key_part++, seg++) + { + uint flag= key_part->key_type; + Field *field= key_part->field; + if (pos->algorithm == HA_KEY_ALG_BTREE) + seg->type= field->key_type(); + else + { + if (!f_is_packed(flag) && + f_packtype(flag) == (int) FIELD_TYPE_DECIMAL && + !(flag & FIELDFLAG_BINARY)) + seg->type= (int) HA_KEYTYPE_TEXT; + else + seg->type= (int) HA_KEYTYPE_BINARY; + } + seg->start= (uint) key_part->offset; + seg->length= (uint) key_part->length; + seg->flag = 0; + seg->charset= field->binary() ? NULL : ((Field_str*)field)->charset(); + if (field->null_ptr) + { + seg->null_bit= field->null_bit; + seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]); + } + else + { + seg->null_bit= 0; + seg->null_pos= 0; + } + if (field->flags & AUTO_INCREMENT_FLAG) + { + auto_key= key + 1; + auto_key_type= field->key_type(); + } + } + } + mem_per_row+= MY_ALIGN(table->reclength + 1, sizeof(char*)); + max_rows = (ulong) (current_thd->variables.max_heap_table_size / + mem_per_row); + HP_CREATE_INFO hp_create_info; + hp_create_info.auto_key= auto_key; + hp_create_info.auto_key_type= auto_key_type; + hp_create_info.auto_increment= (create_info->auto_increment_value ? + create_info->auto_increment_value - 1 : 0); + error= heap_create(fn_format(buff,name,"","",4+2), + table->keys,keydef, table->reclength, + ((table->max_rows < max_rows && table->max_rows) ? + table->max_rows : max_rows), + table->min_rows, &hp_create_info); + my_free((gptr) keydef, MYF(0)); + if (file) + info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE); + ref_length= sizeof(HEAP_PTR); + return (error); +} -int ha_heap::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info) +void ha_heap::update_create_info(HA_CREATE_INFO *create_info) +{ + table->file->info(HA_STATUS_AUTO); + if (!(create_info->used_fields & HA_CREATE_USED_AUTO)) + create_info->auto_increment_value= auto_increment_value; +} +longlong ha_heap::get_auto_increment() { - char buff[FN_REFLEN]; - return heap_create(fn_format(buff,name,"","",4+2)); + ha_heap::info(HA_STATUS_AUTO); + return auto_increment_value; } |