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:
@ -1,17 +1,18 @@
|
|||||||
DROP TABLE IF EXISTS t620;
|
drop table if exists t1;
|
||||||
CREATE TABLE t620 (
|
CREATE TABLE t1 (
|
||||||
recid int(11) NOT NULL auto_increment,
|
recid int(11) NOT NULL auto_increment,
|
||||||
dyninfo text,
|
dyninfo text,
|
||||||
PRIMARY KEY (recid)
|
PRIMARY KEY (recid)
|
||||||
) TYPE=MyISAM;
|
) ENGINE=MyISAM;
|
||||||
INSERT INTO t620 VALUES (1,'color=\"STB,NPG\"\r\nengine=\"J30A13\"\r\nframe=\"MRHCG1640YP4\"\r\ngrade=\"V6\"\r\nmodel=\"ACCORD\"\r\nmodelcode=\"CG164YEN\"\r\ntype=\"VT6\"\r\n');
|
INSERT INTO t1 VALUES (1,'color=\"STB,NPG\"\r\nengine=\"J30A13\"\r\nframe=\"MRHCG1640YP4\"\r\ngrade=\"V6\"\r\nmodel=\"ACCORD\"\r\nmodelcode=\"CG164YEN\"\r\ntype=\"VT6\"\r\n');
|
||||||
INSERT INTO t620 VALUES (2,'color=\"HTM,NPG,DEG,RGS\"\r\nengine=\"F23A5YP1\"\r\nframe=\"MRHCF8640YP3\"\r\ngrade=\"EXi AT\"\r\nmodel=\"ACCORD\"\r\nmodelcode=\"CF864YE\"\r\ntype=\"EXA\"\r\n');
|
INSERT INTO t1 VALUES (2,'color=\"HTM,NPG,DEG,RGS\"\r\nengine=\"F23A5YP1\"\r\nframe=\"MRHCF8640YP3\"\r\ngrade=\"EXi AT\"\r\nmodel=\"ACCORD\"\r\nmodelcode=\"CF864YE\"\r\ntype=\"EXA\"\r\n');
|
||||||
SELECT DISTINCT
|
SELECT DISTINCT
|
||||||
(IF( LOCATE( 'year=\"', dyninfo ) = 1,
|
(IF( LOCATE( 'year=\"', dyninfo ) = 1,
|
||||||
SUBSTRING( dyninfo, 6+1, LOCATE('\"\r',dyninfo) - 6 -1),
|
SUBSTRING( dyninfo, 6+1, LOCATE('\"\r',dyninfo) - 6 -1),
|
||||||
IF( LOCATE( '\nyear=\"', dyninfo ),
|
IF( LOCATE( '\nyear=\"', dyninfo ),
|
||||||
SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) + 7,
|
SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) + 7,
|
||||||
LOCATE( '\"\r', SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) +7 )) - 1), '' ))) AS year
|
LOCATE( '\"\r', SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) +7 )) - 1), '' ))) AS year
|
||||||
FROM t620
|
FROM t1
|
||||||
HAVING year != '' ORDER BY year;
|
HAVING year != '' ORDER BY year;
|
||||||
year
|
year
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -300,3 +300,16 @@ SELECT COUNT(*) FROM t1 WHERE (c=0 and b=1) or (c=0 and a=1);
|
|||||||
COUNT(*)
|
COUNT(*)
|
||||||
6
|
6
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 ( a int not null, b int not null, INDEX ab(a,b) );
|
||||||
|
INSERT INTO t1 VALUES (47,1), (70,1), (15,1), (15, 4);
|
||||||
|
SELECT * FROM t1
|
||||||
|
WHERE
|
||||||
|
(
|
||||||
|
( b =1 AND a BETWEEN 14 AND 21 ) OR
|
||||||
|
( b =2 AND a BETWEEN 16 AND 18 ) OR
|
||||||
|
( b =3 AND a BETWEEN 15 AND 19 ) OR
|
||||||
|
(a BETWEEN 19 AND 47)
|
||||||
|
);
|
||||||
|
a b
|
||||||
|
15 1
|
||||||
|
47 1
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
DROP TABLE IF EXISTS t620;
|
--disable_warnings
|
||||||
CREATE TABLE t620 (
|
drop table if exists t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
recid int(11) NOT NULL auto_increment,
|
recid int(11) NOT NULL auto_increment,
|
||||||
dyninfo text,
|
dyninfo text,
|
||||||
PRIMARY KEY (recid)
|
PRIMARY KEY (recid)
|
||||||
) TYPE=MyISAM;
|
) ENGINE=MyISAM;
|
||||||
|
|
||||||
INSERT INTO t620 VALUES (1,'color=\"STB,NPG\"\r\nengine=\"J30A13\"\r\nframe=\"MRHCG1640YP4\"\r\ngrade=\"V6\"\r\nmodel=\"ACCORD\"\r\nmodelcode=\"CG164YEN\"\r\ntype=\"VT6\"\r\n');
|
INSERT INTO t1 VALUES (1,'color=\"STB,NPG\"\r\nengine=\"J30A13\"\r\nframe=\"MRHCG1640YP4\"\r\ngrade=\"V6\"\r\nmodel=\"ACCORD\"\r\nmodelcode=\"CG164YEN\"\r\ntype=\"VT6\"\r\n');
|
||||||
INSERT INTO t620 VALUES (2,'color=\"HTM,NPG,DEG,RGS\"\r\nengine=\"F23A5YP1\"\r\nframe=\"MRHCF8640YP3\"\r\ngrade=\"EXi AT\"\r\nmodel=\"ACCORD\"\r\nmodelcode=\"CF864YE\"\r\ntype=\"EXA\"\r\n');
|
INSERT INTO t1 VALUES (2,'color=\"HTM,NPG,DEG,RGS\"\r\nengine=\"F23A5YP1\"\r\nframe=\"MRHCF8640YP3\"\r\ngrade=\"EXi AT\"\r\nmodel=\"ACCORD\"\r\nmodelcode=\"CF864YE\"\r\ntype=\"EXA\"\r\n');
|
||||||
|
|
||||||
SELECT DISTINCT
|
SELECT DISTINCT
|
||||||
(IF( LOCATE( 'year=\"', dyninfo ) = 1,
|
(IF( LOCATE( 'year=\"', dyninfo ) = 1,
|
||||||
@ -14,5 +17,7 @@ SELECT DISTINCT
|
|||||||
IF( LOCATE( '\nyear=\"', dyninfo ),
|
IF( LOCATE( '\nyear=\"', dyninfo ),
|
||||||
SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) + 7,
|
SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) + 7,
|
||||||
LOCATE( '\"\r', SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) +7 )) - 1), '' ))) AS year
|
LOCATE( '\"\r', SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) +7 )) - 1), '' ))) AS year
|
||||||
FROM t620
|
FROM t1
|
||||||
HAVING year != '' ORDER BY year;
|
HAVING year != '' ORDER BY year;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -238,7 +238,7 @@ SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test error with
|
# Test problem with range optimzer and sub ranges
|
||||||
#
|
#
|
||||||
|
|
||||||
CREATE TABLE t1 (a int, b int, c int, INDEX (c,a,b));
|
CREATE TABLE t1 (a int, b int, c int, INDEX (c,a,b));
|
||||||
@ -249,3 +249,17 @@ SELECT COUNT(*) FROM t1 WHERE (c=0 and a=1) or (c=0 and b=1);
|
|||||||
SELECT COUNT(*) FROM t1 WHERE (c=0 and b=1) or (c=0 and a=1);
|
SELECT COUNT(*) FROM t1 WHERE (c=0 and b=1) or (c=0 and a=1);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test problem with range optimization over overlapping ranges (#2448)
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 ( a int not null, b int not null, INDEX ab(a,b) );
|
||||||
|
INSERT INTO t1 VALUES (47,1), (70,1), (15,1), (15, 4);
|
||||||
|
SELECT * FROM t1
|
||||||
|
WHERE
|
||||||
|
(
|
||||||
|
( b =1 AND a BETWEEN 14 AND 21 ) OR
|
||||||
|
( b =2 AND a BETWEEN 16 AND 18 ) OR
|
||||||
|
( b =3 AND a BETWEEN 15 AND 19 ) OR
|
||||||
|
(a BETWEEN 19 AND 47)
|
||||||
|
);
|
||||||
|
@ -4747,7 +4747,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||||||
berkeley_env_flags|= DB_TXN_NOSYNC;
|
berkeley_env_flags|= DB_TXN_NOSYNC;
|
||||||
else
|
else
|
||||||
berkeley_env_flags&= ~DB_TXN_NOSYNC;
|
berkeley_env_flags&= ~DB_TXN_NOSYNC;
|
||||||
printf("berkeley_env_flags: %d, arg '%s'\n", berkeley_env_flags, argument);
|
|
||||||
break;
|
break;
|
||||||
case OPT_BDB_NO_RECOVER:
|
case OPT_BDB_NO_RECOVER:
|
||||||
berkeley_init_flags&= ~(DB_RECOVER);
|
berkeley_init_flags&= ~(DB_RECOVER);
|
||||||
|
@ -1710,6 +1710,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
|
|||||||
return 0; // OOM
|
return 0; // OOM
|
||||||
tmp->copy_max_to_min(&key);
|
tmp->copy_max_to_min(&key);
|
||||||
tmp->increment_use_count(key1->use_count+1);
|
tmp->increment_use_count(key1->use_count+1);
|
||||||
|
/* Increment key count as it may be used for next loop */
|
||||||
|
key.increment_use_count(1);
|
||||||
new_arg->next_key_part=key_or(tmp->next_key_part,key.next_key_part);
|
new_arg->next_key_part=key_or(tmp->next_key_part,key.next_key_part);
|
||||||
key1=key1->insert(new_arg);
|
key1=key1->insert(new_arg);
|
||||||
break;
|
break;
|
||||||
@ -2708,15 +2710,18 @@ int QUICK_SELECT_DESC::get_next()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Heikki changed Sept 11, 2002: since InnoDB does not store the cursor
|
/*
|
||||||
position if READ_KEY_EXACT is used to a primary key with all
|
Heikki changed Sept 11, 2002: since InnoDB does not store the cursor
|
||||||
key columns specified, we must use below HA_READ_KEY_OR_NEXT,
|
position if READ_KEY_EXACT is used to a primary key with all
|
||||||
so that InnoDB stores the cursor position and is able to move
|
key columns specified, we must use below HA_READ_KEY_OR_NEXT,
|
||||||
the cursor one step backward after the search. */
|
so that InnoDB stores the cursor position and is able to move
|
||||||
|
the cursor one step backward after the search. */
|
||||||
|
|
||||||
DBUG_ASSERT(range->flag & NEAR_MAX || range_reads_after_key(range));
|
DBUG_ASSERT(range->flag & NEAR_MAX || range_reads_after_key(range));
|
||||||
/* Note: even if max_key is only a prefix, HA_READ_AFTER_KEY will
|
/*
|
||||||
* do the right thing - go past all keys which match the prefix */
|
Note: even if max_key is only a prefix, HA_READ_AFTER_KEY will
|
||||||
|
do the right thing - go past all keys which match the prefix
|
||||||
|
*/
|
||||||
result=file->index_read(record, (byte*) range->max_key,
|
result=file->index_read(record, (byte*) range->max_key,
|
||||||
range->max_length,
|
range->max_length,
|
||||||
((range->flag & NEAR_MAX) ?
|
((range->flag & NEAR_MAX) ?
|
||||||
|
@ -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',
|
(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 ;
|
uchar *p;
|
||||||
int len,tlen ;
|
int len, tlen;
|
||||||
uchar c,l2bias ;
|
uchar l2bias;
|
||||||
|
|
||||||
tlen= len = strlen (tstr) ;
|
tlen= len= strlen (tstr);
|
||||||
l2bias = 256 - 8 ;
|
l2bias= 256 - 8;
|
||||||
for (p=tstr; tlen > 0; p++,tlen--)
|
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)
|
|
||||||
{
|
{
|
||||||
int *t_ctype0= t_ctype[p[0]];
|
uchar c= *p;
|
||||||
if (isldvowel(*p) && isconsnt(p[1]))
|
|
||||||
|
if (isthai(c))
|
||||||
{
|
{
|
||||||
int *t_ctype1= t_ctype[p[1]];
|
int *t_ctype0= t_ctype[c];
|
||||||
*pRight1++= t_ctype1[0];
|
|
||||||
*pRight2++= t_ctype1[1];
|
if (isconsnt(c))
|
||||||
*pRight3++= t_ctype1[2];
|
l2bias -= 8;
|
||||||
*pRight1++= t_ctype0[0];
|
if (isldvowel(c) && isconsnt(p[1]))
|
||||||
*pRight2++= t_ctype0[1];
|
{
|
||||||
*pRight3++= t_ctype0[2];
|
/* simply swap between leading-vowel and consonant */
|
||||||
p+= 2;
|
*p= p[1];
|
||||||
len--;
|
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
|
else
|
||||||
{
|
{
|
||||||
*pRight1= t_ctype0[0];
|
l2bias-= 8;
|
||||||
if(*pRight1 != IGNORE)
|
*p= to_lower_tis620[c];
|
||||||
pRight1++;
|
|
||||||
*pRight2= t_ctype0[1];
|
|
||||||
if (*pRight2 != IGNORE)
|
|
||||||
pRight2++;
|
|
||||||
*pRight3= t_ctype0[2];
|
|
||||||
if(*pRight3 != IGNORE)
|
|
||||||
pRight3++;
|
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
int my_strnncoll_tis620(const uchar * s1, int len1, const uchar * s2, int len2)
|
||||||
{
|
{
|
||||||
uchar buf[80] ;
|
uchar buf[80] ;
|
||||||
uchar *tc1, *tc2;
|
uchar *tc1, *tc2;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
len1= (int) strnlen((char*) s1,len1);
|
len1= (int) strnlen((char*) s1,len1);
|
||||||
len2= (int) strnlen((char*) s2,len2);
|
len2= (int) strnlen((char*) s2,len2);
|
||||||
if ((len1 + len2 +2) > (int) sizeof(buf))
|
tc1= buf;
|
||||||
tc1 = (uchar *)malloc(len1+len2) ;
|
if ((len1 + len2 +2) > (int) sizeof(buf))
|
||||||
else
|
tc1= (uchar*) malloc(len1+len2);
|
||||||
tc1 = buf ;
|
tc2= tc1 + len1+1;
|
||||||
tc2 = tc1 + len1+1 ;
|
memcpy((char*) tc1, (char*) s1, len1);
|
||||||
strncpy((char *)tc1,(char *)s1,len1) ;
|
tc1[len1]= 0; /* if length(s1)> len1, need to put 'end of string' */
|
||||||
tc1[len1] = 0; // if s1's length > len1, need to put 'end of string'
|
memcpy((char *)tc2, (char *)s2, len2);
|
||||||
strncpy((char *)tc2,(char *)s2,len2) ;
|
tc2[len2]= 0; /* put end of string */
|
||||||
tc2[len2] = 0; // put end of string
|
_thai2sortable(tc1);
|
||||||
_thai2sortable(tc1);
|
_thai2sortable(tc2);
|
||||||
_thai2sortable(tc2);
|
i= strcmp((char*)tc1, (char*)tc2);
|
||||||
i= strcmp((char*)tc1, (char*)tc2);
|
if (tc1 != buf)
|
||||||
if (tc1 != buf )
|
free(tc1);
|
||||||
free(tc1);
|
return i;
|
||||||
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)
|
int my_strnxfrm_tis620(uchar * dest, const uchar * src, int len, int srclen)
|
||||||
{
|
{
|
||||||
if (len > srclen)
|
if (len > srclen)
|
||||||
len = srclen ;
|
len= srclen ;
|
||||||
strncpy (dest,src,len) ;
|
strnmov(dest, src, len) ;
|
||||||
dest[len] = 0; // if src's length > len, need to put 'end of string'
|
dest[len]= 0; /* if length(src) > len, need to put 'end of string' */
|
||||||
_thai2sortable(dest);
|
_thai2sortable(dest);
|
||||||
return strlen(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)
|
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)
|
int my_strxfrm_tis620(uchar * dest, const uchar * src, int len)
|
||||||
{
|
{
|
||||||
return my_strnxfrm_tis620(dest,src,len,strlen((char *)src));
|
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 max_sort_chr ((char) 255)
|
||||||
#define wild_one '_'
|
#define wild_one '_'
|
||||||
#define wild_many '%'
|
#define wild_many '%'
|
||||||
|
|
||||||
my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape,
|
my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape,
|
||||||
uint res_length, char *min_str, char *max_str,
|
uint res_length, char *min_str, char *max_str,
|
||||||
uint *min_length, uint *max_length)
|
uint *min_length, uint *max_length)
|
||||||
{
|
{
|
||||||
const char *end=ptr+ptr_length;
|
const char *end=ptr+ptr_length;
|
||||||
char *min_org=min_str;
|
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);
|
*min_length= (uint) (min_str - min_org);
|
||||||
*max_length=res_length;
|
*max_length=res_length;
|
||||||
do {
|
do {
|
||||||
*min_str++ = ' '; /* Because if key compression */
|
*min_str++ = ' '; /* Because of key compression */
|
||||||
*max_str++ = max_sort_chr;
|
*max_str++ = max_sort_chr;
|
||||||
} while (min_str != min_end);
|
} while (min_str != min_end);
|
||||||
return 0;
|
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);
|
*min_length= *max_length = (uint) (min_str - min_org);
|
||||||
|
|
||||||
while (min_str != min_end)
|
while (min_str != min_end)
|
||||||
*min_str++ = *max_str++ = ' '; /* Because if key compression */
|
*min_str++= *max_str++ = ' '; /* Because of key compression */
|
||||||
return 0;
|
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)
|
void ThNormalize(uchar* ptr, uint field_length, const uchar* from, uint length)
|
||||||
{
|
{
|
||||||
const uchar* fr= from;
|
const uchar *fr= from;
|
||||||
uchar* p= ptr;
|
uchar *p= ptr;
|
||||||
uint i;
|
uint i;
|
||||||
|
|
||||||
if (length > field_length)
|
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++)
|
for (i=0;i<length;i++,p++,fr++)
|
||||||
{
|
{
|
||||||
*p = *fr ;
|
*p= *fr ;
|
||||||
|
|
||||||
/* Sathit's NOTE: it's better idea not to do any normalize
|
/* Sathit's NOTE: it's better idea not to do any normalize */
|
||||||
*/
|
if (istone(*fr) || isdiacrt1(*fr))
|
||||||
if (istone(*fr) || isdiacrt1(*fr))
|
{
|
||||||
{
|
if (i > 0 && (islwrvowel(fr[-1]) || isuprvowel(fr[-1])))
|
||||||
if (i > 0 && (islwrvowel(fr[-1]) || isuprvowel(fr[-1])))
|
continue;
|
||||||
continue ;
|
if(islwrvowel(fr[1]) || isuprvowel(fr[1]))
|
||||||
if(islwrvowel(fr[1]) || isuprvowel(fr[1]))
|
{
|
||||||
{
|
*p= fr[1];
|
||||||
*p= fr[1];
|
p[1]= *fr;
|
||||||
p[1]= *fr;
|
fr++;
|
||||||
fr++;
|
p++;
|
||||||
p++;
|
i++;
|
||||||
i++ ;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user