diff options
Diffstat (limited to 'myisam/mi_search.c')
-rw-r--r-- | myisam/mi_search.c | 407 |
1 files changed, 12 insertions, 395 deletions
diff --git a/myisam/mi_search.c b/myisam/mi_search.c index d57fd1bb5b2..737bb2fd5d3 100644 --- a/myisam/mi_search.c +++ b/myisam/mi_search.c @@ -133,7 +133,7 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, &info->lastkey_length)) goto err; if ((nextflag & SEARCH_LAST) && - _mi_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND, + ha_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND, ¬_used)) { my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */ @@ -191,7 +191,7 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, while (start != end) { mid= (start+end)/2; - if ((flag=_mi_key_cmp(keyinfo->seg,page+(uint) mid*totlength,key,key_len, + if ((flag=ha_key_cmp(keyinfo->seg,page+(uint) mid*totlength,key,key_len, comp_flag,¬_used)) >= 0) end=mid; @@ -199,7 +199,7 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, start=mid+1; } if (mid != start) - flag=_mi_key_cmp(keyinfo->seg,page+(uint) start*totlength,key,key_len, + flag=ha_key_cmp(keyinfo->seg,page+(uint) start*totlength,key,key_len, comp_flag,¬_used); if (flag < 0) start++; /* point at next, bigger key */ @@ -239,7 +239,7 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, length,page,end)); DBUG_RETURN(MI_FOUND_WRONG_KEY); } - if ((flag=_mi_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag, + if ((flag=ha_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag, ¬_used)) >= 0) break; #ifdef EXTRA_DEBUG @@ -262,7 +262,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, { /* my_flag is raw comparison result to be changed according to SEARCH_NO_FIND,SEARCH_LAST and HA_REVERSE_SORT flags. - flag is the value returned by _mi_key_cmp and as treated as final */ + flag is the value returned by ha_key_cmp and as treated as final */ int flag=0, my_flag=-1; uint nod_flag, length, len, matched, cmplen, kseg_len; uint prefix_len,suffix_len; @@ -351,7 +351,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, DBUG_PRINT("loop",("page: '%.*s%.*s'",prefix_len,t_buff+seg_len_pack,suffix_len,vseg)); { uchar *from=vseg+suffix_len; - MI_KEYSEG *keyseg; + HA_KEYSEG *keyseg; uint l; for (keyseg=keyinfo->seg+1 ; keyseg->type ; keyseg++ ) @@ -423,7 +423,7 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, else if (key_len_left>0) { uint not_used; - if ((flag = _mi_key_cmp(keyinfo->seg+1,vseg, + if ((flag = ha_key_cmp(keyinfo->seg+1,vseg, k,key_len_left,nextflag,¬_used)) >= 0) break; } @@ -651,389 +651,6 @@ void _mi_dpointer(MI_INFO *info, uchar *buff, my_off_t pos) } /* _mi_dpointer */ -int _mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length, - uchar *b, uint b_length, my_bool part_key) -{ - int flag; - -#ifdef USE_STRCOLL - if (use_strcoll(charset_info)) - { - if (part_key && b_length < a_length) - a_length=b_length; - return my_strnncoll(charset_info, a, a_length, b, b_length); - } - else -#endif - { - uint length= min(a_length,b_length); - uchar *end= a+ length; - uchar *sort_order=charset_info->sort_order; - while (a < end) - if ((flag= (int) sort_order[*a++] - (int) sort_order[*b++])) - return flag; - } - if (part_key && b_length < a_length) - return 0; - return (int) (a_length-b_length); -} - - -static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length, - my_bool part_key) -{ - uint length= min(a_length,b_length); - uchar *end= a+ length; - int flag; - - while (a < end) - if ((flag= (int) *a++ - (int) *b++)) - return flag; - if (part_key && b_length < a_length) - return 0; - return (int) (a_length-b_length); -} - - - /* - ** Compare two keys - ** Returns <0, 0, >0 acording to which is bigger - ** Key_length specifies length of key to use. Number-keys can't - ** be splited - ** If flag <> SEARCH_FIND compare also position - */ - -#define FCMP(A,B) ((int) (A) - (int) (B)) - -int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a, - register uchar *b, uint key_length, uint nextflag, - uint *diff_pos) -{ - int flag; - int16 s_1,s_2; - int32 l_1,l_2; - uint32 u_1,u_2; - float f_1,f_2; - double d_1,d_2; - uint next_key_length; - - *diff_pos=0; - for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++) - { - uchar *end; - uint piks=! (keyseg->flag & HA_NO_SORT); - (*diff_pos)++; - - /* Handle NULL part */ - if (keyseg->null_bit) - { - key_length--; - if (*a != *b && piks) - { - flag = (int) *a - (int) *b; - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - } - b++; - if (!*a++) /* If key was NULL */ - { - if (nextflag == (SEARCH_FIND | SEARCH_UPDATE)) - nextflag=SEARCH_SAME; /* Allow duplicate keys */ - next_key_length=key_length; - continue; /* To next key part */ - } - } - end= a+ min(keyseg->length,key_length); - next_key_length=key_length-keyseg->length; - - switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_TEXT: /* Ascii; Key is converted */ - if (keyseg->flag & HA_SPACE_PACK) - { - int a_length,b_length,pack_length; - get_key_length(a_length,a); - get_key_pack_length(b_length,pack_length,b); - next_key_length=key_length-b_length-pack_length; - - if (piks && - (flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a+=a_length; - b+=b_length; - break; - } - else - { - uint length=(uint) (end-a), a_length=length, b_length=length; - if (!(nextflag & SEARCH_PREFIX)) - { - while (a_length && a[a_length-1] == ' ') - a_length--; - while (b_length && b[b_length-1] == ' ') - b_length--; - } - if (piks && - (flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a=end; - b+=length; - } - break; - case HA_KEYTYPE_BINARY: - if (keyseg->flag & HA_SPACE_PACK) - { - int a_length,b_length,pack_length; - get_key_length(a_length,a); - get_key_pack_length(b_length,pack_length,b); - next_key_length=key_length-b_length-pack_length; - - if (piks && - (flag=compare_bin(a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a+=a_length; - b+=b_length; - break; - } - else - { - uint length=keyseg->length; - if (piks && - (flag=compare_bin(a,length,b,length, - (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a+=length; - b+=length; - } - break; - case HA_KEYTYPE_VARTEXT: - { - int a_length,b_length,pack_length; - get_key_length(a_length,a); - get_key_pack_length(b_length,pack_length,b); - next_key_length=key_length-b_length-pack_length; - - if (piks && - (flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a+=a_length; - b+=b_length; - break; - } - break; - case HA_KEYTYPE_VARBINARY: - { - int a_length,b_length,pack_length; - get_key_length(a_length,a); - get_key_pack_length(b_length,pack_length,b); - next_key_length=key_length-b_length-pack_length; - - if (piks && - (flag=compare_bin(a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a+=a_length; - b+=b_length; - break; - } - break; - case HA_KEYTYPE_INT8: - { - int i_1= (int) *((signed char*) a); - int i_2= (int) *((signed char*) b); - if (piks && (flag = CMP_NUM(i_1,i_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b++; - break; - } - case HA_KEYTYPE_SHORT_INT: - s_1= mi_sint2korr(a); - s_2= mi_sint2korr(b); - if (piks && (flag = CMP_NUM(s_1,s_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 2; /* sizeof(short int); */ - break; - case HA_KEYTYPE_USHORT_INT: - { - uint16 us_1,us_2; - us_1= mi_sint2korr(a); - us_2= mi_sint2korr(b); - if (piks && (flag = CMP_NUM(us_1,us_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+=2; /* sizeof(short int); */ - break; - } - case HA_KEYTYPE_LONG_INT: - l_1= mi_sint4korr(a); - l_2= mi_sint4korr(b); - if (piks && (flag = CMP_NUM(l_1,l_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 4; /* sizeof(long int); */ - break; - case HA_KEYTYPE_ULONG_INT: - u_1= mi_sint4korr(a); - u_2= mi_sint4korr(b); - if (piks && (flag = CMP_NUM(u_1,u_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 4; /* sizeof(long int); */ - break; - case HA_KEYTYPE_INT24: - l_1=mi_sint3korr(a); - l_2=mi_sint3korr(b); - if (piks && (flag = CMP_NUM(l_1,l_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 3; - break; - case HA_KEYTYPE_UINT24: - l_1=mi_uint3korr(a); - l_2=mi_uint3korr(b); - if (piks && (flag = CMP_NUM(l_1,l_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 3; - break; - case HA_KEYTYPE_FLOAT: - mi_float4get(f_1,a); - mi_float4get(f_2,b); - if (piks && (flag = CMP_NUM(f_1,f_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 4; /* sizeof(float); */ - break; - case HA_KEYTYPE_DOUBLE: - mi_float8get(d_1,a); - mi_float8get(d_2,b); - if (piks && (flag = CMP_NUM(d_1,d_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 8; /* sizeof(double); */ - break; - case HA_KEYTYPE_NUM: /* Numeric key */ - { - int swap_flag= 0; - int alength,blength; - - if (keyseg->flag & HA_REVERSE_SORT) - { - swap(uchar*,a,b); - swap_flag=1; /* Remember swap of a & b */ - end= a+ (int) (end-b); - } - if (keyseg->flag & HA_SPACE_PACK) - { - alength= *a++; blength= *b++; - end=a+alength; - next_key_length=key_length-blength-1; - } - else - { - alength= (int) (end-a); - blength=keyseg->length; - /* remove pre space from keys */ - for ( ; alength && *a == ' ' ; a++, alength--) ; - for ( ; blength && *b == ' ' ; b++, blength--) ; - } - if (piks) - { - if (*a == '-') - { - if (*b != '-') - return -1; - a++; b++; - swap(uchar*,a,b); - swap(int,alength,blength); - swap_flag=1-swap_flag; - alength--; blength--; - end=a+alength; - } - else if (*b == '-') - return 1; - while (alength && (*a == '+' || *a == '0')) - { - a++; alength--; - } - while (blength && (*b == '+' || *b == '0')) - { - b++; blength--; - } - if (alength != blength) - return (alength < blength) ? -1 : 1; - while (a < end) - if (*a++ != *b++) - return ((int) a[-1] - (int) b[-1]); - } - else - { - b+=(end-a); - a=end; - } - - if (swap_flag) /* Restore pointers */ - swap(uchar*,a,b); - break; - } -#ifdef HAVE_LONG_LONG - case HA_KEYTYPE_LONGLONG: - { - longlong ll_a,ll_b; - ll_a= mi_sint8korr(a); - ll_b= mi_sint8korr(b); - if (piks && (flag = CMP_NUM(ll_a,ll_b))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 8; - break; - } - case HA_KEYTYPE_ULONGLONG: - { - ulonglong ll_a,ll_b; - ll_a= mi_uint8korr(a); - ll_b= mi_uint8korr(b); - if (piks && (flag = CMP_NUM(ll_a,ll_b))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 8; - break; - } -#endif - case HA_KEYTYPE_END: /* Ready */ - goto end; /* diff_pos is incremented */ - } - } - (*diff_pos)++; -end: - if (!(nextflag & SEARCH_FIND)) - { - uint i; - if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST)) /* Find record after key */ - return (nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1; - flag=0; - for (i=keyseg->length ; i-- > 0 ; ) - { - if (*a++ != *b++) - { - flag= FCMP(a[-1],b[-1]); - break; - } - } - if (nextflag & SEARCH_SAME) - return (flag); /* read same */ - if (nextflag & SEARCH_BIGGER) - return (flag <= 0 ? -1 : 1); /* read next */ - return (flag < 0 ? -1 : 1); /* read previous */ - } - return 0; -} /* _mi_key_cmp */ - - /* Get key from key-block */ /* page points at previous key; its advanced to point at next key */ /* key should contain previous key */ @@ -1057,7 +674,7 @@ uint _mi_get_static_key(register MI_KEYDEF *keyinfo, uint nod_flag, uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, register uchar **page_pos, register uchar *key) { - reg1 MI_KEYSEG *keyseg; + reg1 HA_KEYSEG *keyseg; uchar *start_key,*page=*page_pos; uint length; @@ -1190,7 +807,7 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, register uchar **page_pos, register uchar *key) { - reg1 MI_KEYSEG *keyseg; + reg1 HA_KEYSEG *keyseg; uchar *start_key,*page=*page_pos,*page_end,*from,*from_end; uint length,tmp; @@ -1389,7 +1006,7 @@ uchar *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uint _mi_keylength(MI_KEYDEF *keyinfo, register uchar *key) { - reg1 MI_KEYSEG *keyseg; + reg1 HA_KEYSEG *keyseg; uchar *start; if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY))) @@ -1655,7 +1272,7 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key, uchar *org_key, uchar *prev_key, uchar *key, MI_KEY_PARAM *s_temp) { - reg1 MI_KEYSEG *keyseg; + reg1 HA_KEYSEG *keyseg; int length; uint key_length,ref_length,org_key_length=0, length_pack,new_key_length,diff_flag,pack_marker; @@ -1670,7 +1287,7 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key, if ((keyinfo->flag & HA_FULLTEXT) && ((keyseg->type == HA_KEYTYPE_TEXT) || (keyseg->type == HA_KEYTYPE_VARTEXT)) && - !use_strcoll(keyseg->charset)) + !use_strnxfrm(keyseg->charset)) sort_order=keyseg->charset->sort_order; /* diff flag contains how many bytes is needed to pack key */ |