1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Fixed problem with range optimization over overlapping ranges (#2448)

This commit is contained in:
monty@mysql.com
2004-02-04 09:51:13 +01:00
parent 5d7ffa49ec
commit f7e65a7620
7 changed files with 195 additions and 223 deletions

View File

@ -449,225 +449,160 @@ uchar NEAR sort_order_tis620[]=
(uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377',
};
/* Convert thai string to "Standard C String Function" sortable string
Arg: const source string and length of converted string
Ret: Sortable string
/*
Convert thai string to "Standard C String Function" sortable string
Arg: const source string and length of converted string
Ret: Sortable string
*/
static void _thai2sortable(uchar *tstr)
static void _thai2sortable(uchar *tstr)
{
uchar *p ;
int len,tlen ;
uchar c,l2bias ;
uchar *p;
int len, tlen;
uchar l2bias;
tlen= len = strlen (tstr) ;
l2bias = 256 - 8 ;
for (p=tstr; tlen > 0; p++,tlen--)
{
c = *p ;
if (isthai(c))
{
int *t_ctype0 = t_ctype[c] ;
if (isconsnt(c))
l2bias -= 8 ;
if (isldvowel(c) && isconsnt(p[1]))
{
/*
simply swap between leading-vowel and consonant
*/
*p = p[1];
p[1]= c ;
tlen-- ;
p++;
continue ;
}
// if found level 2 char (L2_GARAN,L2_TONE*,L2_TYKHU) move to last
if (t_ctype0[1]>= L2_GARAN)
{
// l2bias use to control position weight of l2char
// example (*=l2char) XX*X must come before X*XX
strcpy (p,p+1) ;
tstr[len-1] = l2bias + t_ctype0[1]- L2_GARAN +1 ;
p-- ;
continue ;
}
}
else
{
l2bias -= 8 ;
*p = to_lower_tis620[c];
}
/*
this routine skip non-printable char
but not necessary, leave it like raw ascii 8 bits
*/
/*
t_ctype0 = t_ctype[p[0]];
if ((t_ctype0[0]|t_ctype0[1]|t_ctype0[2])==IGNORE)
{
strcpy(p,p+1);
p-- ;
}
*/
}
}
/*
NOTE: isn't it faster to alloc buffer in calling function?
*/
/*
Sathit's NOTE: we don't use this function anymore
static uchar* thai2sortable(const uchar * tstr,int len)
{
*/
/* We use only 3 levels (neglect capitalization). */
/*
const uchar* p= tstr;
uchar *outBuf;
uchar *pRight1, *pRight2, *pRight3;
uchar *pLeft1, *pLeft2, *pLeft3;
uint bufSize;
uint RightSize;
len= (int) strnlen((char*) tstr,len);
bufSize= (uint) buffsize((char*) tstr);
RightSize= sizeof(uchar) * (len + 1);
if (!(outBuf= pLeft1= pRight1=
(uchar *)malloc(sizeof(uchar) * bufSize + RightSize*2)))
return (uchar*) tstr;
pLeft2= pRight2= pRight1 + sizeof(uchar) * bufSize;
pLeft3= pRight3= pRight2 + RightSize;
while (--len > 0)
tlen= len= strlen (tstr);
l2bias= 256 - 8;
for (p= tstr; tlen > 0; p++, tlen--)
{
int *t_ctype0= t_ctype[p[0]];
if (isldvowel(*p) && isconsnt(p[1]))
uchar c= *p;
if (isthai(c))
{
int *t_ctype1= t_ctype[p[1]];
*pRight1++= t_ctype1[0];
*pRight2++= t_ctype1[1];
*pRight3++= t_ctype1[2];
*pRight1++= t_ctype0[0];
*pRight2++= t_ctype0[1];
*pRight3++= t_ctype0[2];
p+= 2;
len--;
int *t_ctype0= t_ctype[c];
if (isconsnt(c))
l2bias -= 8;
if (isldvowel(c) && isconsnt(p[1]))
{
/* simply swap between leading-vowel and consonant */
*p= p[1];
p[1]= c;
tlen--;
p++;
continue;
}
/* if found level 2 char (L2_GARAN,L2_TONE*,L2_TYKHU) move to last */
if (t_ctype0[1] >= L2_GARAN)
{
/*
l2bias use to control position weight of l2char
example (*=l2char) XX*X must come before X*XX
*/
strmov(p,p+1);
tstr[len-1]= l2bias + t_ctype0[1]- L2_GARAN +1;
p--;
continue;
}
}
else
{
*pRight1= t_ctype0[0];
if(*pRight1 != IGNORE)
pRight1++;
*pRight2= t_ctype0[1];
if (*pRight2 != IGNORE)
pRight2++;
*pRight3= t_ctype0[2];
if(*pRight3 != IGNORE)
pRight3++;
p++;
l2bias-= 8;
*p= to_lower_tis620[c];
}
}
if (!len)
{
int *t_ctype0= t_ctype[p[0]];
*pRight1= t_ctype0[0];
if (*pRight1 != IGNORE)
pRight1++;
*pRight2= t_ctype0[1];
if (*pRight2 != IGNORE)
pRight2++;
*pRight3= t_ctype0[2];
if (*pRight3 != IGNORE)
pRight3++;
}
*pRight1++= L2_BLANK;
*pRight2++= L3_BLANK;
*pRight3++= '\0';
memcpy(pRight1, pLeft2, pRight2 - pLeft2);
pRight1+= pRight2 - pLeft2;
memcpy(pRight1, pLeft3, pRight3 - pLeft3);
return outBuf;
}
/*
strncoll() replacement, compare 2 string, both are converted to sortable
string
Arg: 2 Strings and it compare length
Ret: strcmp result
*/
/* strncoll() replacement, compare 2 string, both are conveted to sortable string
Arg: 2 Strings and it compare length
Ret: strcmp result
*/
int my_strnncoll_tis620(const uchar * s1, int len1, const uchar * s2, int len2)
{
uchar buf[80] ;
uchar *tc1, *tc2;
int i;
uchar buf[80] ;
uchar *tc1, *tc2;
int i;
len1= (int) strnlen((char*) s1,len1);
len2= (int) strnlen((char*) s2,len2);
if ((len1 + len2 +2) > (int) sizeof(buf))
tc1 = (uchar *)malloc(len1+len2) ;
else
tc1 = buf ;
tc2 = tc1 + len1+1 ;
strncpy((char *)tc1,(char *)s1,len1) ;
tc1[len1] = 0; // if s1's length > len1, need to put 'end of string'
strncpy((char *)tc2,(char *)s2,len2) ;
tc2[len2] = 0; // put end of string
_thai2sortable(tc1);
_thai2sortable(tc2);
i= strcmp((char*)tc1, (char*)tc2);
if (tc1 != buf )
free(tc1);
return i;
len1= (int) strnlen((char*) s1,len1);
len2= (int) strnlen((char*) s2,len2);
tc1= buf;
if ((len1 + len2 +2) > (int) sizeof(buf))
tc1= (uchar*) malloc(len1+len2);
tc2= tc1 + len1+1;
memcpy((char*) tc1, (char*) s1, len1);
tc1[len1]= 0; /* if length(s1)> len1, need to put 'end of string' */
memcpy((char *)tc2, (char *)s2, len2);
tc2[len2]= 0; /* put end of string */
_thai2sortable(tc1);
_thai2sortable(tc2);
i= strcmp((char*)tc1, (char*)tc2);
if (tc1 != buf)
free(tc1);
return i;
}
/* strnxfrm replacment, convert Thai string to sortable string
Arg: Destination buffer, source string, dest length and source length
Ret: Conveted string size
/*
strnxfrm replacment, convert Thai string to sortable string
Arg: Destination buffer, source string, dest length and source length
Ret: Conveted string size
*/
int my_strnxfrm_tis620(uchar * dest, const uchar * src, int len, int srclen)
{
if (len > srclen)
len = srclen ;
strncpy (dest,src,len) ;
dest[len] = 0; // if src's length > len, need to put 'end of string'
_thai2sortable(dest);
return strlen(dest);
if (len > srclen)
len= srclen ;
strnmov(dest, src, len) ;
dest[len]= 0; /* if length(src) > len, need to put 'end of string' */
_thai2sortable(dest);
return strlen(dest);
}
/* strcoll replacment, compare 2 strings
Arg: 2 strings
Ret: strcmp result
/*
strcoll replacment, compare 2 strings
Arg: 2 strings
Ret: strcmp result
*/
int my_strcoll_tis620(const uchar * s1, const uchar * s2)
{
return my_strnncoll_tis620(s1, strlen((char *)s1),s2,strlen((char *)s2));
return my_strnncoll_tis620(s1, strlen((char *)s1),s2,strlen((char *)s2));
}
/* strxfrm replacment, convert Thai string to sortable string
Arg: Destination buffer, String and dest buffer size
Ret: Converting string size
/*
strxfrm replacment, convert Thai string to sortable string
Arg: Destination buffer, String and dest buffer size
Ret: Converting string size
*/
int my_strxfrm_tis620(uchar * dest, const uchar * src, int len)
{
return my_strnxfrm_tis620(dest,src,len,strlen((char *)src));
}
/* Convert SQL like string to C string
Arg: String, its length, escape character, resource length, minimal string and maximum string
Ret: Alway 0
/*
Convert SQL LIKE string to C string
Arg: String, its length, escape character, resource length,
minimal string and maximum string
Ret: Always 0
*/
/*
We just copy this function from opt_range.cc. No need to convert to
thai2sortable string. min_str and max_str will be use for comparison and
converted there.
*/
/* We just copy this function from opt_range.cc. No need to convert to
thai2sortable string. min_str and max_str will be use for comparison and
converted there. */
#define max_sort_chr ((char) 255)
#define wild_one '_'
#define wild_many '%'
my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape,
uint res_length, char *min_str, char *max_str,
uint *min_length, uint *max_length)
uint res_length, char *min_str, char *max_str,
uint *min_length, uint *max_length)
{
const char *end=ptr+ptr_length;
char *min_org=min_str;
@ -692,7 +627,7 @@ my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape,
*min_length= (uint) (min_str - min_org);
*max_length=res_length;
do {
*min_str++ = ' '; /* Because if key compression */
*min_str++ = ' '; /* Because of key compression */
*max_str++ = max_sort_chr;
} while (min_str != min_end);
return 0;
@ -702,18 +637,21 @@ my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape,
*min_length= *max_length = (uint) (min_str - min_org);
while (min_str != min_end)
*min_str++ = *max_str++ = ' '; /* Because if key compression */
*min_str++= *max_str++ = ' '; /* Because of key compression */
return 0;
}
/* Thai normalization for input sub system
Arg: Buffer, 's length, String, 'length
Ret: Void
/*
Thai normalization for input sub system
Arg: Buffer, 's length, String, 'length
*/
void ThNormalize(uchar* ptr, uint field_length, const uchar* from, uint length)
{
const uchar* fr= from;
uchar* p= ptr;
const uchar *fr= from;
uchar *p= ptr;
uint i;
if (length > field_length)
@ -721,24 +659,21 @@ void ThNormalize(uchar* ptr, uint field_length, const uchar* from, uint length)
for (i=0;i<length;i++,p++,fr++)
{
*p = *fr ;
*p= *fr ;
/* Sathit's NOTE: it's better idea not to do any normalize
*/
if (istone(*fr) || isdiacrt1(*fr))
{
if (i > 0 && (islwrvowel(fr[-1]) || isuprvowel(fr[-1])))
continue ;
if(islwrvowel(fr[1]) || isuprvowel(fr[1]))
{
*p= fr[1];
p[1]= *fr;
fr++;
p++;
i++ ;
}
/* Sathit's NOTE: it's better idea not to do any normalize */
if (istone(*fr) || isdiacrt1(*fr))
{
if (i > 0 && (islwrvowel(fr[-1]) || isuprvowel(fr[-1])))
continue;
if(islwrvowel(fr[1]) || isuprvowel(fr[1]))
{
*p= fr[1];
p[1]= *fr;
fr++;
p++;
i++;
}
}
}
}