summaryrefslogtreecommitdiff
path: root/myisam
diff options
context:
space:
mode:
authorunknown <ingo@mysql.com>2005-08-29 18:18:30 +0200
committerunknown <ingo@mysql.com>2005-08-29 18:18:30 +0200
commit194a520d215ff8a3f5fd672e3bb1fc991ec38dc8 (patch)
treed775a19ce336b9046b4bba8758999a325c8182fe /myisam
parent27201ccb064b7b2e851ada4610d7b20ffc37679d (diff)
parentea363750277d129ff466c51fd7e278d09c85a709 (diff)
downloadmariadb-git-194a520d215ff8a3f5fd672e3bb1fc991ec38dc8.tar.gz
Merge mysql.com:/home/mydev/mysql-4.1-4100
into mysql.com:/home/mydev/mysql-5.0-5000 myisam/mi_search.c: Auto merged mysql-test/r/alter_table.result: Auto merged mysql-test/t/alter_table.test: Auto merged mysql-test/t/innodb.test: Auto merged sql/sql_table.cc: Auto merged mysql-test/r/innodb.result: Hand merged. mysql-test/r/key.result: Hand merged. mysql-test/r/myisam.result: Hand merged. mysql-test/t/key.test: Hand merged. mysql-test/t/myisam.test: Hand merged. sql/sql_delete.cc: Hand merged. sql/sql_parse.cc: Hand merged.
Diffstat (limited to 'myisam')
-rw-r--r--myisam/mi_search.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/myisam/mi_search.c b/myisam/mi_search.c
index ed61bbfe41a..b7360dba7f3 100644
--- a/myisam/mi_search.c
+++ b/myisam/mi_search.c
@@ -318,19 +318,21 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
get_key_pack_length(kseg_len,length_pack,kseg);
key_len_skip=length_pack+kseg_len;
key_len_left=(int) key_len- (int) key_len_skip;
+ /* If key_len is 0, then lenght_pack is 1, then key_len_left is -1. */
cmplen=(key_len_left>=0) ? kseg_len : key_len-length_pack;
DBUG_PRINT("info",("key: '%.*s'",kseg_len,kseg));
/*
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 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
- next-key-seg Next key segments
+ (prefix) length The high bit is set if this is a prefix for the prev key.
+ [suffix length] Packed length of suffix if the previous was a prefix.
+ (suffix) data Key data bytes (past the common prefix or whole segment).
+ [next-key-seg] Next key segments (([packed length], data), ...)
+ pointer Reference to the data file (last_keyseg->length).
*/
matched=0; /* how many char's from prefix were alredy matched */
@@ -351,16 +353,23 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
if (packed)
{
- if (suffix_len == 0) /* Same key */
+ if (suffix_len == 0)
+ {
+ /* == 0x80 or 0x8000, same key, prefix length == old key length. */
prefix_len=len;
+ }
else
{
+ /* > 0x80 or 0x8000, this is prefix lgt, packed suffix lgt follows. */
prefix_len=suffix_len;
get_key_length(suffix_len,vseg);
}
}
else
+ {
+ /* Not packed. No prefix used from last key. */
prefix_len=0;
+ }
len=prefix_len+suffix_len;
seg_len_pack=get_pack_length(len);
@@ -417,7 +426,12 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
uint left;
uchar *k=kseg+prefix_len;
- left=(len>cmplen) ? cmplen-prefix_len : suffix_len;
+ /*
+ If prefix_len > cmplen then we are in the end-space comparison
+ phase. Do not try to acces the key any more ==> left= 0.
+ */
+ left= ((len <= cmplen) ? suffix_len :
+ ((prefix_len < cmplen) ? cmplen - prefix_len : 0));
matched=prefix_len+left;
@@ -455,7 +469,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
my_flag= -1;
else
{
- /* We have to compare k and vseg as if they where space extended */
+ /* We have to compare k and vseg as if they were space extended */
uchar *end= k+ (cmplen - len);
for ( ; k < end && *k == ' '; k++) ;
if (k == end)
@@ -474,7 +488,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
if ((nextflag & SEARCH_PREFIX) && key_len_left == 0)
goto fix_flag;
- /* We have to compare k and vseg as if they where space extended */
+ /* We have to compare k and vseg as if they were space extended */
for (end=vseg + (len-cmplen) ;
vseg < end && *vseg == (uchar) ' ';
vseg++, matched++) ;