summaryrefslogtreecommitdiff
path: root/sql/ha_heap.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/ha_heap.cc')
-rw-r--r--sql/ha_heap.cc220
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;
}