summaryrefslogtreecommitdiff
path: root/myisam
diff options
context:
space:
mode:
authorunknown <ingo@mysql.com>2005-04-08 14:13:02 +0200
committerunknown <ingo@mysql.com>2005-04-08 14:13:02 +0200
commit7ff8fc73c994756582bb260861de0f819a20da94 (patch)
tree8a313ebce33fd21f19bbbf1fd9abd09bee3ddf7c /myisam
parent98e615ba35952f3999f26aaa567b4744a71fbfdc (diff)
downloadmariadb-git-7ff8fc73c994756582bb260861de0f819a20da94.tar.gz
Bug#9188 - Corruption Can't open file: 'table.MYI' (errno: 145)
Since 4.1 keys are compared with trailing spaces. Thus, a "x " key can be inserted between a couple of "x" keys. The existing code did not take this into account. Though the comments in the code claimed it did. myisam/mi_search.c: Bug#9188 - Corruption Can't open file: 'table.MYI' (errno: 145) Fixed some function comments. In the case when we insert a different key between two identical keys, the difference must be additional spaces. In this case the prefix is the same as that of the new key instead of the (zero) remaining length. myisam/mi_write.c: Bug#9188 - Corruption Can't open file: 'table.MYI' (errno: 145) Fixed a function comment. mysql-test/r/myisam.result: Bug#9188 - Corruption Can't open file: 'table.MYI' (errno: 145) The test result. mysql-test/t/myisam.test: Bug#9188 - Corruption Can't open file: 'table.MYI' (errno: 145) The test case.
Diffstat (limited to 'myisam')
-rw-r--r--myisam/mi_search.c51
-rw-r--r--myisam/mi_write.c26
2 files changed, 67 insertions, 10 deletions
diff --git a/myisam/mi_search.c b/myisam/mi_search.c
index bc8be9c2732..390e32b679d 100644
--- a/myisam/mi_search.c
+++ b/myisam/mi_search.c
@@ -210,9 +210,31 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
} /* _mi_bin_search */
- /* Used instead of _mi_bin_search() when key is packed */
- /* Puts smaller or identical key in buff */
- /* Key is searched sequentially */
+/*
+ Locate a packed key in a key page.
+
+ SYNOPSIS
+ _mi_seq_search()
+ info Open table information.
+ keyinfo Key definition information.
+ page Key page (beginning).
+ key Search key.
+ key_len Length to use from search key or USE_WHOLE_KEY
+ comp_flag Search flags like SEARCH_SAME etc.
+ ret_pos RETURN Position in key page behind this key.
+ buff RETURN Copy of previous or identical unpacked key.
+ last_key RETURN If key is last in page.
+
+ DESCRIPTION
+ Used instead of _mi_bin_search() when key is packed.
+ Puts smaller or identical key in buff.
+ Key is searched sequentially.
+
+ RETURN
+ > 0 Key in 'buff' is smaller than search key.
+ 0 Key in 'buff' is identical to search key.
+ < 0 Not found.
+*/
int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
@@ -718,7 +740,19 @@ uint _mi_get_static_key(register MI_KEYDEF *keyinfo, uint nod_flag,
} /* _mi_get_static_key */
-/* Key with is packed against previous key or key with a NULL column */
+/*
+ get key witch is packed against previous key or key with a NULL column.
+
+ SYNOPSIS
+ _mi_get_pack_key()
+ keyinfo key definition information.
+ nod_flag If nod: Length of node pointer, else zero.
+ page_pos RETURN position in key page behind this key.
+ key IN/OUT in: prev key, out: unpacked key.
+
+ RETURN
+ key_length + length of data pointer
+*/
uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
register uchar **page_pos, register uchar *key)
@@ -1339,12 +1373,12 @@ _mi_calc_var_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
Keys are compressed the following way:
- If the max length of first key segment <= 127 characters the prefix is
+ If the max length of first key segment <= 127 bytes the prefix is
1 byte else it's 2 byte
- prefix byte The high bit is set if this is a prefix for the prev key
+ prefix byte(s) The high bit is set if this is a prefix for the prev key
length Packed length if the previous was a prefix byte
- [length] Length character of data
+ [length] data bytes ('length' bytes)
next-key-seg Next key segments
If the first segment can have NULL:
@@ -1537,7 +1571,8 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
s_temp->part_of_prev_key= new_ref_length;
s_temp->prev_length= org_key_length -
(new_ref_length-pack_marker);
- s_temp->n_ref_length= s_temp->n_length= s_temp->prev_length;
+ s_temp->n_ref_length= s_temp->part_of_prev_key;
+ s_temp->n_length= s_temp->prev_length;
n_length= get_pack_length(s_temp->prev_length);
s_temp->prev_key+= (new_ref_length - pack_marker);
length+= s_temp->prev_length + n_length;
diff --git a/myisam/mi_write.c b/myisam/mi_write.c
index 7d053ddfd22..cd9e73fba22 100644
--- a/myisam/mi_write.c
+++ b/myisam/mi_write.c
@@ -414,8 +414,30 @@ err:
} /* w_search */
- /* Insert new key at right of key_pos */
- /* Returns 2 if key contains key to upper level */
+/*
+ Insert new key.
+
+ SYNOPSIS
+ _mi_insert()
+ info Open table information.
+ keyinfo Key definition information.
+ key New key.
+ anc_buff Key page (beginning).
+ key_pos Position in key page where to insert.
+ key_buff Copy of previous key.
+ father_buff parent key page for balancing.
+ father_key_pos position in parent key page for balancing.
+ father_page position of parent key page in file.
+ insert_last If to append at end of page.
+
+ DESCRIPTION
+ Insert new key at right of key_pos.
+
+ RETURN
+ 2 if key contains key to upper level.
+ 0 OK.
+ < 0 Error.
+*/
int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo,
uchar *key, uchar *anc_buff, uchar *key_pos, uchar *key_buff,