summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bar@bar.intranet.mysql.r18.ru>2004-02-03 14:03:01 +0400
committerunknown <bar@bar.intranet.mysql.r18.ru>2004-02-03 14:03:01 +0400
commit92bcbf9a43e2d74ee323f5e768923bfc289e83ce (patch)
tree37c3b5800cab311b8e2aba688e423fc076328a5d
parente0b0ec6b2c98f05547018655b6030a8d62bc511f (diff)
downloadmariadb-git-92bcbf9a43e2d74ee323f5e768923bfc289e83ce.tar.gz
Thai tis620 crash problem in text comparison routines was fixed.
-rw-r--r--mysql-test/r/ctype_tis620.result17
-rw-r--r--mysql-test/t/ctype_tis620-master.opt1
-rw-r--r--mysql-test/t/ctype_tis620.test18
-rw-r--r--strings/ctype-tis620.c177
4 files changed, 158 insertions, 55 deletions
diff --git a/mysql-test/r/ctype_tis620.result b/mysql-test/r/ctype_tis620.result
new file mode 100644
index 00000000000..d939fd12e60
--- /dev/null
+++ b/mysql-test/r/ctype_tis620.result
@@ -0,0 +1,17 @@
+DROP TABLE IF EXISTS t620;
+CREATE TABLE t620 (
+recid int(11) NOT NULL auto_increment,
+dyninfo text,
+PRIMARY KEY (recid)
+) TYPE=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 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');
+SELECT DISTINCT
+(IF( LOCATE( 'year=\"', dyninfo ) = 1,
+SUBSTRING( dyninfo, 6+1, LOCATE('\"\r',dyninfo) - 6 -1),
+IF( LOCATE( '\nyear=\"', dyninfo ),
+SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) + 7,
+LOCATE( '\"\r', SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) +7 )) - 1), '' ))) AS year
+FROM t620
+HAVING year != '' ORDER BY year;
+year
diff --git a/mysql-test/t/ctype_tis620-master.opt b/mysql-test/t/ctype_tis620-master.opt
new file mode 100644
index 00000000000..69d47c06e42
--- /dev/null
+++ b/mysql-test/t/ctype_tis620-master.opt
@@ -0,0 +1 @@
+--default-character-set=tis620
diff --git a/mysql-test/t/ctype_tis620.test b/mysql-test/t/ctype_tis620.test
new file mode 100644
index 00000000000..7a0555515e1
--- /dev/null
+++ b/mysql-test/t/ctype_tis620.test
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS t620;
+CREATE TABLE t620 (
+ recid int(11) NOT NULL auto_increment,
+ dyninfo text,
+ PRIMARY KEY (recid)
+) TYPE=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 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');
+
+SELECT DISTINCT
+ (IF( LOCATE( 'year=\"', dyninfo ) = 1,
+ SUBSTRING( dyninfo, 6+1, LOCATE('\"\r',dyninfo) - 6 -1),
+ IF( LOCATE( '\nyear=\"', dyninfo ),
+ SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) + 7,
+ LOCATE( '\"\r', SUBSTRING( dyninfo, LOCATE( '\nyear=\"', dyninfo ) +7 )) - 1), '' ))) AS year
+FROM t620
+HAVING year != '' ORDER BY year;
diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c
index 7ffc83ea005..5cd718f5944 100644
--- a/strings/ctype-tis620.c
+++ b/strings/ctype-tis620.c
@@ -15,6 +15,10 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
+ Copyright (C) 2003 by Sathit Jittanupat <jsat66@hotmail.com,jsat66@yahoo.com>
+ * solving bug crash with long text field string
+ * sorting with different number of space or sign char. within string
+
Copyright (C) 2001 by Korakot Chaovavanich <korakot@iname.com> and
Apisilp Trunganont <apisilp@pantip.inet.co.th>
Copyright (C) 1998, 1999 by Pruet Boonma <pruet@eng.cmu.ac.th>
@@ -49,10 +53,6 @@
#include "m_ctype.h"
#include "t_ctype.h"
-static uchar* thai2sortable(const uchar *tstr,int len);
-
-#define BUFFER_MULTIPLY 4
-#define buffsize(s) (BUFFER_MULTIPLY * (strlen(s) + 1))
#define M L_MIDDLE
#define U L_UPPER
#define L L_LOWER
@@ -453,13 +453,77 @@ uchar NEAR sort_order_tis620[]=
Arg: const source string and length of converted string
Ret: Sortable string
*/
+static void _thai2sortable(uchar *tstr)
+{
+ uchar *p ;
+ int len,tlen ;
+ uchar c,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;
@@ -526,6 +590,7 @@ static uchar* thai2sortable(const uchar * tstr,int len)
memcpy(pRight1, pLeft3, pRight3 - pLeft3);
return outBuf;
}
+*/
/* strncoll() replacement, compare 2 string, both are conveted to sortable string
Arg: 2 Strings and it compare length
@@ -533,16 +598,27 @@ static uchar* thai2sortable(const uchar * tstr,int len)
*/
int my_strnncoll_tis620(const uchar * s1, int len1, const uchar * s2, int len2)
{
- uchar *tc1, *tc2;
- int i;
- tc1= thai2sortable(s1, len1);
- tc2= thai2sortable(s2, len2);
- i= strcmp((char*)tc1, (char*)tc2);
- if (tc1 != s1)
- free(tc1);
- if (tc2 != s2)
- free(tc2);
- return 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;
}
/* strnxfrm replacment, convert Thai string to sortable string
@@ -551,15 +627,12 @@ int my_strnncoll_tis620(const uchar * s1, int len1, const uchar * s2, int len2)
*/
int my_strnxfrm_tis620(uchar * dest, const uchar * src, int len, int srclen)
{
- uint bufSize;
- uchar *tmp;
- bufSize= (uint) buffsize((char*)src);
- tmp= thai2sortable(src,srclen);
- set_if_smaller(bufSize,(uint) len);
- memcpy((uchar *)dest, tmp, bufSize);
- if (tmp != src)
- free(tmp);
- return (int)bufSize;
+ 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);
}
/* strcoll replacment, compare 2 strings
@@ -568,16 +641,7 @@ int my_strnxfrm_tis620(uchar * dest, const uchar * src, int len, int srclen)
*/
int my_strcoll_tis620(const uchar * s1, const uchar * s2)
{
- uchar *tc1, *tc2;
- int i;
- tc1= thai2sortable(s1, (int) strlen((char*)s1));
- tc2= thai2sortable(s2, (int) strlen((char*)s2));
- i= strcmp((char*)tc1, (char*)tc2);
- if (tc1 != s1)
- free(tc1);
- if (tc2 != s2)
- free(tc2);
- return i;
+ return my_strnncoll_tis620(s1, strlen((char *)s1),s2,strlen((char *)s2));
}
/* strxfrm replacment, convert Thai string to sortable string
@@ -586,15 +650,7 @@ int my_strcoll_tis620(const uchar * s1, const uchar * s2)
*/
int my_strxfrm_tis620(uchar * dest, const uchar * src, int len)
{
- uint bufSize;
- uchar *tmp;
-
- bufSize= (uint)buffsize((char*) src);
- tmp= thai2sortable(src, len);
- memcpy((uchar *)dest, tmp, bufSize);
- if (tmp != src)
- free(tmp);
- return bufSize;
+ return my_strnxfrm_tis620(dest,src,len,strlen((char *)src));
}
/* Convert SQL like string to C string
@@ -658,20 +714,31 @@ void ThNormalize(uchar* ptr, uint field_length, const uchar* from, uint length)
{
const uchar* fr= from;
uchar* p= ptr;
+ uint i;
if (length > field_length)
length= field_length;
- while (length--)
- if ((istone(*fr) || isdiacrt1(*fr)) &&
- (islwrvowel(fr[1]) || isuprvowel(fr[1])))
- {
- *p= fr[1];
- p[1]= *fr;
- fr+= 2;
- p+= 2;
- length--;
+ for (i=0;i<length;i++,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++ ;
+ }
}
- else
- *p++ = *fr++;
+
+ }
+
}