diff options
author | unknown <monty@mysql.com> | 2004-12-06 19:18:35 +0200 |
---|---|---|
committer | unknown <monty@mysql.com> | 2004-12-06 19:18:35 +0200 |
commit | 8379b61efb053da778846416baf23812a26e8f86 (patch) | |
tree | 44698f6f68c51daacf7552356ae071b8e8fdb035 /strings | |
parent | 19a95482195a158425c66ac629d07da53e4fc1b6 (diff) | |
parent | a8ea31fae6737c453d2dd9719a75f905c06048b3 (diff) | |
download | mariadb-git-8379b61efb053da778846416baf23812a26e8f86.tar.gz |
Merge with new VARCHAR code
configure.in:
Auto merged
BitKeeper/deleted/.del-acinclude.m4~f4ab416bac5003:
Auto merged
BitKeeper/deleted/.del-ha_isam.cc~4dce65904db2675e:
Auto merged
BitKeeper/deleted/.del-ha_isammrg.cc~dc682e4755d77a2e:
Auto merged
client/mysqldump.c:
Auto merged
client/mysqltest.c:
Auto merged
heap/hp_create.c:
Auto merged
heap/hp_delete.c:
Auto merged
heap/hp_hash.c:
Auto merged
heap/hp_write.c:
Auto merged
include/decimal.h:
Auto merged
include/m_ctype.h:
Auto merged
libmysql/libmysql.c:
Auto merged
libmysqld/Makefile.am:
Auto merged
myisam/mi_check.c:
Auto merged
myisam/mi_create.c:
Auto merged
myisam/mi_write.c:
Auto merged
mysql-test/r/ctype_tis620.result:
Auto merged
mysql-test/r/ctype_ucs.result:
Auto merged
mysql-test/r/myisam.result:
Auto merged
mysql-test/r/mysqldump.result:
Auto merged
mysql-test/r/order_by.result:
Auto merged
mysql-test/r/ps.result:
Auto merged
mysql-test/r/ps_1general.result:
Auto merged
mysql-test/r/ps_2myisam.result:
Auto merged
mysql-test/r/ps_3innodb.result:
Auto merged
mysql-test/r/ps_4heap.result:
Auto merged
mysql-test/r/ps_5merge.result:
Auto merged
mysql-test/r/ps_6bdb.result:
Auto merged
mysql-test/r/select.result:
Auto merged
mysql-test/r/strict.result:
Auto merged
mysql-test/r/subselect.result:
Auto merged
mysql-test/r/type_blob.result:
Auto merged
mysql-test/t/ctype_ucs.test:
Auto merged
mysql-test/t/endspace.test:
Auto merged
mysql-test/t/myisam.test:
Auto merged
mysql-test/t/ps_1general.test:
Auto merged
mysql-test/t/strict.test:
Auto merged
mysql-test/t/type_blob.test:
Auto merged
ndb/src/common/util/NdbSqlUtil.cpp:
Auto merged
scripts/mysql_fix_privilege_tables.sh:
Auto merged
sql/field.h:
Auto merged
sql/field_conv.cc:
Auto merged
sql/ha_heap.cc:
Auto merged
sql/ha_innodb.cc:
Auto merged
sql/ha_innodb.h:
Auto merged
sql/ha_myisam.cc:
Auto merged
sql/ha_ndbcluster.cc:
Auto merged
sql/handler.h:
Auto merged
sql/item_cmpfunc.cc:
Auto merged
sql/item_sum.cc:
Auto merged
sql/opt_range.cc:
Auto merged
sql/opt_sum.cc:
Auto merged
sql/protocol.cc:
Auto merged
sql/sql_base.cc:
Auto merged
sql/sql_help.cc:
Auto merged
sql/sql_select.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
sql/structs.h:
Auto merged
sql/table.cc:
Auto merged
strings/ctype-czech.c:
Auto merged
strings/ctype-uca.c:
Auto merged
strings/ctype-utf8.c:
Auto merged
strings/ctype-win1250ch.c:
Auto merged
strings/decimal.c:
Auto merged
tests/client_test.c:
Auto merged
mysql-test/r/bdb.result:
Merge with VARCHAR code
mysql-test/r/heap.result:
Merge with VARCHAR code
mysql-test/r/innodb.result:
Merge with VARCHAR code
mysql-test/r/select.result.es:
Merge with VARCHAR code
mysql-test/t/bdb.test:
Merge with VARCHAR code
mysql-test/t/heap.test:
Merge with VARCHAR code
mysql-test/t/innodb.test:
Merge with VARCHAR code
sql/field.cc:
Merge with VARCHAR code
sql/item.cc:
Merge with VARCHAR code
sql/sql_acl.cc:
Merge with VARCHAR code
sql/sql_parse.cc:
Merge with VARCHAR code
sql/sql_table.cc:
Merge with VARCHAR code
sql/sql_update.cc:
Merge with VARCHAR code
sql/table.h:
Merge with VARCHAR code
strings/ctype-mb.c:
Don't pad my_like_range with max_str for simple LIKE expression
strings/ctype-tis620.c:
Merge with VARCHAR code
strings/ctype-ucs2.c:
Added new argument to my_strnncollsp_ucs2()
Simply code
Diffstat (limited to 'strings')
-rw-r--r-- | strings/ctype-big5.c | 36 | ||||
-rw-r--r-- | strings/ctype-bin.c | 21 | ||||
-rw-r--r-- | strings/ctype-czech.c | 18 | ||||
-rw-r--r-- | strings/ctype-gbk.c | 27 | ||||
-rw-r--r-- | strings/ctype-latin1.c | 17 | ||||
-rw-r--r-- | strings/ctype-mb.c | 33 | ||||
-rw-r--r-- | strings/ctype-simple.c | 40 | ||||
-rw-r--r-- | strings/ctype-sjis.c | 31 | ||||
-rw-r--r-- | strings/ctype-tis620.c | 29 | ||||
-rw-r--r-- | strings/ctype-uca.c | 36 | ||||
-rw-r--r-- | strings/ctype-ucs2.c | 30 | ||||
-rw-r--r-- | strings/ctype-utf8.c | 33 | ||||
-rw-r--r-- | strings/ctype-win1250ch.c | 17 | ||||
-rw-r--r-- | strings/decimal.c | 9 |
14 files changed, 282 insertions, 95 deletions
diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 8345c53202c..d9532cddc4d 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -264,24 +264,33 @@ static int my_strnncoll_big5(CHARSET_INFO *cs __attribute__((unused)), static int my_strnncollsp_big5(CHARSET_INFO * cs __attribute__((unused)), const uchar *a, uint a_length, - const uchar *b, uint b_length) + const uchar *b, uint b_length, + my_bool diff_if_only_endspace_difference) { uint length= min(a_length, b_length); int res= my_strnncoll_big5_internal(&a, &b, length); + +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif + if (!res && a_length != b_length) { const uchar *end; int swap= 0; + if (diff_if_only_endspace_difference) + res= 1; /* Assume 'a' is bigger */ /* Check the next not space character of the longer key. If it's < ' ', then it's smaller than the other key. */ if (a_length < b_length) { - /* put shorter key in a */ + /* put longer key in a */ a_length= b_length; a= b; - swap= -1; /* swap sign of result */ + swap= -1; /* swap sign of result */ + res= -res; } for (end= a + a_length-length; a < end ; a++) { @@ -407,7 +416,7 @@ static my_bool my_like_range_big5(CHARSET_INFO *cs __attribute__((unused)), *min_str++= *max_str++ = *ptr; continue; } - if (*ptr == w_one) /* '_' in SQL */ + if (*ptr == w_one) /* '_' in SQL */ { *min_str++='\0'; /* This should be min char */ *max_str++=max_sort_char; @@ -415,7 +424,13 @@ static my_bool my_like_range_big5(CHARSET_INFO *cs __attribute__((unused)), } if (*ptr == w_many) /* '%' in SQL */ { - *min_length= (uint) (min_str-min_org); + /* + Calculate length of keys: + 'a\0\0... is the smallest possible string when we have space expand + a\ff\ff... is the biggest possible string + */ + *min_length= ((cs->state & MY_CS_BINSORT) ? (uint) (min_str - min_org) : + res_length); *max_length= res_length; do { *min_str++ = 0; @@ -425,26 +440,27 @@ static my_bool my_like_range_big5(CHARSET_INFO *cs __attribute__((unused)), } *min_str++= *max_str++ = *ptr; } - *min_length= *max_length= (uint) (min_str-min_org); + + *min_length= *max_length= (uint) (min_str-min_org); while (min_str != min_end) - { - *min_str++ = ' '; /* Because if key compression */ - *max_str++ = ' '; - } + *min_str++= *max_str++= ' '; return 0; } + static int ismbchar_big5(CHARSET_INFO *cs __attribute__((unused)), const char* p, const char *e) { return (isbig5head(*(p)) && (e)-(p)>1 && isbig5tail(*((p)+1))? 2: 0); } + static int mbcharlen_big5(CHARSET_INFO *cs __attribute__((unused)), uint c) { return (isbig5head(c)? 2 : 1); } + /* page 0 0xA140-0xC7FC */ static uint16 tab_big5_uni0[]={ 0x3000,0xFF0C,0x3001,0x3002,0xFF0E,0x2022,0xFF1B,0xFF1A, diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 7d17f62c8d0..db57c75d9f1 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -103,7 +103,9 @@ static int my_strnncoll_binary(CHARSET_INFO * cs __attribute__((unused)), static int my_strnncollsp_binary(CHARSET_INFO * cs __attribute__((unused)), const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference + __attribute__((unused))) { return my_strnncoll_binary(cs,s,slen,t,tlen,0); } @@ -130,6 +132,9 @@ static int my_strnncoll_8bit_bin(CHARSET_INFO * cs __attribute__((unused)), slen Length of 's' t String to compare tlen Length of 't' + diff_if_only_endspace_difference + Set to 1 if the strings should be regarded as different + if they only difference in end space NOTE This function is used for character strings with binary collations. @@ -144,10 +149,16 @@ static int my_strnncoll_8bit_bin(CHARSET_INFO * cs __attribute__((unused)), static int my_strnncollsp_8bit_bin(CHARSET_INFO * cs __attribute__((unused)), const uchar *a, uint a_length, - const uchar *b, uint b_length) + const uchar *b, uint b_length, + my_bool diff_if_only_endspace_difference) { const uchar *end; uint length; + int res; + +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif end= a + (length= min(a_length, b_length)); while (a < end) @@ -155,6 +166,7 @@ static int my_strnncollsp_8bit_bin(CHARSET_INFO * cs __attribute__((unused)), if (*a++ != *b++) return ((int) a[-1] - (int) b[-1]); } + res= 0; if (a_length != b_length) { int swap= 0; @@ -162,12 +174,15 @@ static int my_strnncollsp_8bit_bin(CHARSET_INFO * cs __attribute__((unused)), Check the next not space character of the longer key. If it's < ' ', then it's smaller than the other key. */ + if (diff_if_only_endspace_difference) + res= 1; /* Assume 'a' is bigger */ if (a_length < b_length) { /* put shorter key in s */ a_length= b_length; a= b; swap= -1; /* swap sign of result */ + res= -res; } for (end= a + a_length-length; a < end ; a++) { @@ -175,7 +190,7 @@ static int my_strnncollsp_8bit_bin(CHARSET_INFO * cs __attribute__((unused)), return ((int) *a - (int) ' ') ^ swap; } } - return 0; + return res; } diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index 2177a18504e..07c45788d30 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -275,8 +275,9 @@ static int my_strnncoll_czech(CHARSET_INFO *cs __attribute__((unused)), static int my_strnncollsp_czech(CHARSET_INFO * cs, - const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *s, uint slen, + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference) { for ( ; slen && s[slen-1] == ' ' ; slen--); for ( ; tlen && t[tlen-1] == ' ' ; tlen--); @@ -352,7 +353,7 @@ static int my_strnxfrm_czech(CHARSET_INFO *cs __attribute__((unused)), #ifdef REAL_MYSQL -#define min_sort_char ' ' +#define min_sort_char 0 #define max_sort_char '9' #define EXAMPLE @@ -391,8 +392,17 @@ static my_bool my_like_range_czech(CHARSET_INFO *cs __attribute__((unused)), *min_str++= *max_str++ = *ptr; } - *min_length= (uint) (min_str - min_org); + + if (cs->state & MY_CS_BINSORT) + *min_length= (uint) (min_str - min_org); + else + { + /* 'a\0\0... is the smallest possible string */ + *min_length= res_length; + } + /* a\ff\ff... is the biggest possible string */ *max_length= res_length; + while (min_str != min_end) { *min_str++ = min_sort_char; /* Because of key compression */ diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 0be56e8d946..858624c0600 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -2625,14 +2625,22 @@ int my_strnncoll_gbk(CHARSET_INFO *cs __attribute__((unused)), static int my_strnncollsp_gbk(CHARSET_INFO * cs __attribute__((unused)), const uchar *a, uint a_length, - const uchar *b, uint b_length) + const uchar *b, uint b_length, + my_bool diff_if_only_endspace_difference) { uint length= min(a_length, b_length); int res= my_strnncoll_gbk_internal(&a, &b, length); + +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif + if (!res && a_length != b_length) { const uchar *end; int swap= 0; + if (diff_if_only_endspace_difference) + res= 1; /* Assume 'a' is bigger */ /* Check the next not space character of the longer key. If it's < ' ', then it's smaller than the other key. @@ -2643,6 +2651,7 @@ static int my_strnncollsp_gbk(CHARSET_INFO * cs __attribute__((unused)), a_length= b_length; a= b; swap= -1; /* swap sign of result */ + res= -res; } for (end= a + a_length-length; a < end ; a++) { @@ -2728,22 +2737,26 @@ static my_bool my_like_range_gbk(CHARSET_INFO *cs __attribute__((unused)), } if (*ptr == w_many) /* '%' in SQL */ { - *min_length= (uint) (min_str - min_org); + /* + Calculate length of keys: + 'a\0\0... is the smallest possible string when we have space expand + a\ff\ff... is the biggest possible string + */ + *min_length= ((cs->state & MY_CS_BINSORT) ? (uint) (min_str - min_org) : + res_length); *max_length= res_length; do { *min_str++= 0; - *max_str++ = max_sort_char; + *max_str++= max_sort_char; } while (min_str != min_end); return 0; } *min_str++= *max_str++ = *ptr; } + *min_length= *max_length = (uint) (min_str - min_org); while (min_str != min_end) - { - *min_str++ = ' '; /* Because if key compression */ - *max_str++ = ' '; - } + *min_str++= *max_str++= ' '; /* Because if key compression */ return 0; } diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c index 5f1850b7772..69c9ed4b023 100644 --- a/strings/ctype-latin1.c +++ b/strings/ctype-latin1.c @@ -572,11 +572,16 @@ static int my_strnncoll_latin1_de(CHARSET_INFO *cs __attribute__((unused)), static int my_strnncollsp_latin1_de(CHARSET_INFO *cs __attribute__((unused)), const uchar *a, uint a_length, - const uchar *b, uint b_length) + const uchar *b, uint b_length, + my_bool diff_if_only_endspace_difference) { - const uchar *a_end= a + a_length; - const uchar *b_end= b + b_length; + const uchar *a_end= a + a_length, *b_end= b + b_length; uchar a_char, a_extend= 0, b_char, b_extend= 0; + int res; + +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif while ((a < a_end || a_extend) && (b < b_end || b_extend)) { @@ -609,9 +614,12 @@ static int my_strnncollsp_latin1_de(CHARSET_INFO *cs __attribute__((unused)), if (b_extend) return -1; + res= 0; if (a != a_end || b != b_end) { int swap= 0; + if (diff_if_only_endspace_difference) + res= 1; /* Assume 'a' is bigger */ /* Check the next not space character of the longer key. If it's < ' ', then it's smaller than the other key. @@ -622,6 +630,7 @@ static int my_strnncollsp_latin1_de(CHARSET_INFO *cs __attribute__((unused)), a_end= b_end; a= b; swap= -1; /* swap sign of result */ + res= -res; } for ( ; a < a_end ; a++) { @@ -629,7 +638,7 @@ static int my_strnncollsp_latin1_de(CHARSET_INFO *cs __attribute__((unused)), return ((int) *a - (int) ' ') ^ swap; } } - return 0; + return res; } diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 3cdf7f460cd..ae81cefad5a 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -362,6 +362,9 @@ static int my_strnncoll_mb_bin(CHARSET_INFO * cs __attribute__((unused)), slen Length of 's' t String to compare tlen Length of 't' + diff_if_only_endspace_difference + Set to 1 if the strings should be regarded as different + if they only difference in end space NOTE This function is used for character strings with binary collations. @@ -376,10 +379,16 @@ static int my_strnncoll_mb_bin(CHARSET_INFO * cs __attribute__((unused)), static int my_strnncollsp_mb_bin(CHARSET_INFO * cs __attribute__((unused)), const uchar *a, uint a_length, - const uchar *b, uint b_length) + const uchar *b, uint b_length, + my_bool diff_if_only_endspace_difference) { const uchar *end; uint length; + int res; + +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif end= a + (length= min(a_length, b_length)); while (a < end) @@ -387,9 +396,12 @@ static int my_strnncollsp_mb_bin(CHARSET_INFO * cs __attribute__((unused)), if (*a++ != *b++) return ((int) a[-1] - (int) b[-1]); } + res= 0; if (a_length != b_length) { int swap= 0; + if (diff_if_only_endspace_difference) + res= 1; /* Assume 'a' is bigger */ /* Check the next not space character of the longer key. If it's < ' ', then it's smaller than the other key. @@ -400,6 +412,7 @@ static int my_strnncollsp_mb_bin(CHARSET_INFO * cs __attribute__((unused)), a_length= b_length; a= b; swap= -1; /* swap sign of result */ + res= -res; } for (end= a + a_length-length; a < end ; a++) { @@ -407,7 +420,7 @@ static int my_strnncollsp_mb_bin(CHARSET_INFO * cs __attribute__((unused)), return ((int) *a - (int) ' ') ^ swap; } } - return 0; + return res; } @@ -523,9 +536,15 @@ my_bool my_like_range_mb(CHARSET_INFO *cs, if (charlen < (uint) (min_str - min_org)) min_str= min_org + charlen; - /* Write min key */ - *min_length= (uint) (min_str - min_org); + /* + Calculate length of keys: + 'a\0\0... is the smallest possible string when we have space expand + a\ff\ff... is the biggest possible string + */ + *min_length= ((cs->state & MY_CS_BINSORT) ? (uint) (min_str - min_org) : + res_length); *max_length= res_length; + /* Create min key */ do { *min_str++= (char) cs->min_sort_char; @@ -541,14 +560,14 @@ my_bool my_like_range_mb(CHARSET_INFO *cs, } *min_str++= *max_str++ = *ptr; } - *min_length= *max_length = (uint) (min_str - min_org); + *min_length= *max_length = (uint) (min_str - min_org); while (min_str != min_end) - *min_str++= ' '; /* Because if key compression */ - pad_max_char(cs, max_str, max_end); + *min_str++= *max_str= ' '; /* Because if key compression */ return 0; } + static int my_wildcmp_mb_bin(CHARSET_INFO *cs, const char *str,const char *str_end, const char *wildstr,const char *wildend, diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index a019665a235..0659cb5d387 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -71,6 +71,9 @@ int my_strnncoll_simple(CHARSET_INFO * cs, const uchar *s, uint slen, a_length Length of 'a' b Second string to compare b_length Length of 'b' + diff_if_only_endspace_difference + Set to 1 if the strings should be regarded as different + if they only difference in end space IMPLEMENTATION If one string is shorter as the other, then we space extend the other @@ -89,10 +92,16 @@ int my_strnncoll_simple(CHARSET_INFO * cs, const uchar *s, uint slen, */ int my_strnncollsp_simple(CHARSET_INFO * cs, const uchar *a, uint a_length, - const uchar *b, uint b_length) + const uchar *b, uint b_length, + my_bool diff_if_only_endspace_difference) { const uchar *map= cs->sort_order, *end; uint length; + int res; + +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif end= a + (length= min(a_length, b_length)); while (a < end) @@ -100,9 +109,12 @@ int my_strnncollsp_simple(CHARSET_INFO * cs, const uchar *a, uint a_length, if (map[*a++] != map[*b++]) return ((int) map[a[-1]] - (int) map[b[-1]]); } + res= 0; if (a_length != b_length) { int swap= 0; + if (diff_if_only_endspace_difference) + res= 1; /* Assume 'a' is bigger */ /* Check the next not space character of the longer key. If it's < ' ', then it's smaller than the other key. @@ -113,6 +125,7 @@ int my_strnncollsp_simple(CHARSET_INFO * cs, const uchar *a, uint a_length, a_length= b_length; a= b; swap= -1; /* swap sign of result */ + res= -res; } for (end= a + a_length-length; a < end ; a++) { @@ -120,7 +133,7 @@ int my_strnncollsp_simple(CHARSET_INFO * cs, const uchar *a, uint a_length, return ((int) *a - (int) ' ') ^ swap; } } - return 0; + return res; } @@ -218,14 +231,19 @@ void my_hash_sort_simple(CHARSET_INFO *cs, ulong *nr1, ulong *nr2) { register uchar *sort_order=cs->sort_order; - const uchar *pos = key; + const uchar *end= key + len; - key+= len; + /* + Remove end space. We have to do this to be able to compare + 'A ' and 'A' as identical + */ + while (end > key && end[-1] == ' ') + end--; - for (; pos < (uchar*) key ; pos++) + for (; key < (uchar*) end ; key++) { nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) * - ((uint) sort_order[(uint) *pos])) + (nr1[0] << 8); + ((uint) sort_order[(uint) *key])) + (nr1[0] << 8); nr2[0]+=3; } } @@ -996,8 +1014,10 @@ my_bool my_like_range_simple(CHARSET_INFO *cs, } if (*ptr == w_many) /* '%' in SQL */ { - *min_length= (uint) (min_str - min_org); - *max_length=res_length; + /* Calculate length of keys */ + *min_length= ((cs->state & MY_CS_BINSORT) ? (uint) (min_str - min_org) : + res_length); + *max_length= res_length; do { *min_str++= 0; @@ -1007,10 +1027,10 @@ my_bool my_like_range_simple(CHARSET_INFO *cs, } *min_str++= *max_str++ = *ptr; } - *min_length= *max_length = (uint) (min_str - min_org); + *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 if key compression */ return 0; } diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index a8b5394f8c5..12bee9082b6 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -244,14 +244,21 @@ static int my_strnncoll_sjis(CHARSET_INFO *cs __attribute__((unused)), static int my_strnncollsp_sjis(CHARSET_INFO *cs __attribute__((unused)), const uchar *a, uint a_length, - const uchar *b, uint b_length) + const uchar *b, uint b_length, + my_bool diff_if_only_endspace_difference) { - const uchar *a_end= a + a_length; - const uchar *b_end= b + b_length; + const uchar *a_end= a + a_length, *b_end= b + b_length; int res= my_strnncoll_sjis_internal(cs, &a, a_length, &b, b_length); + +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif + if (!res && (a != a_end || b != b_end)) { int swap= 0; + if (diff_if_only_endspace_difference) + res= 1; /* Assume 'a' is bigger */ /* Check the next not space character of the longer key. If it's < ' ', then it's smaller than the other key. @@ -262,6 +269,7 @@ static int my_strnncollsp_sjis(CHARSET_INFO *cs __attribute__((unused)), a_end= b_end; a= b; swap= -1; /* swap sign of result */ + res= -res; } for (; a < a_end ; a++) { @@ -347,8 +355,14 @@ static my_bool my_like_range_sjis(CHARSET_INFO *cs __attribute__((unused)), } if (*ptr == w_many) { /* '%' in SQL */ - *min_length = (uint)(min_str - min_org); - *max_length = res_length; + /* + Calculate length of keys: + 'a\0\0... is the smallest possible string when we have space expand + a\ff\ff... is the biggest possible string + */ + *min_length= ((cs->state & MY_CS_BINSORT) ? (uint) (min_str - min_org) : + res_length); + *max_length= res_length; do { *min_str++= 0; @@ -358,9 +372,10 @@ static my_bool my_like_range_sjis(CHARSET_INFO *cs __attribute__((unused)), } *min_str++ = *max_str++ = *ptr++; } - *min_length = *max_length = (uint)(min_str - min_org); - while (min_str < min_end) - *min_str++ = *max_str++ = ' '; /* Because if key compression */ + + *min_length= *max_length= (uint) (min_str - min_org); + while (min_str != min_end) + *min_str++= *max_str++= ' '; /* Because if key compression */ return 0; } diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 5d37aa965d9..ab432c0d71f 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -320,7 +320,7 @@ static int t_ctype[][TOT_LEVELS] = { /*0xFC*/ { IGNORE, IGNORE, IGNORE, IGNORE, X }, /*0xFD*/ { IGNORE, IGNORE, IGNORE, IGNORE, X }, /*0xFE*/ { IGNORE, IGNORE, IGNORE, IGNORE, X }, -/* Utilize 0xFF for max_sort_chr in my_like_range_tis620 */ + /* Utilize 0xFF for max_sort_chr in my_like_range_tis620 */ /*0xFF*/ { 255 /*IGNORE*/, IGNORE, IGNORE, IGNORE, X }, }; @@ -559,12 +559,16 @@ int my_strnncoll_tis620(CHARSET_INFO *cs __attribute__((unused)), static int my_strnncollsp_tis620(CHARSET_INFO * cs __attribute__((unused)), const uchar *a0, uint a_length, - const uchar *b0, uint b_length) + const uchar *b0, uint b_length, + my_bool diff_if_only_endspace_difference) { - uchar buf[80] ; - uchar *end, *a, *b, *alloced= NULL; + uchar buf[80], *end, *a, *b, alloced= NULL; uint length; int res= 0; + +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif a= buf; if ((a_length + b_length +2) > (int) sizeof(buf)) @@ -590,6 +594,8 @@ int my_strnncollsp_tis620(CHARSET_INFO * cs __attribute__((unused)), if (a_length != b_length) { int swap= 0; + if (diff_if_only_endspace_difference) + res= 1; /* Assume 'a' is bigger */ /* Check the next not space character of the longer key. If it's < ' ', then it's smaller than the other key. @@ -600,6 +606,7 @@ int my_strnncollsp_tis620(CHARSET_INFO * cs __attribute__((unused)), a_length= b_length; a= b; swap= -1; /* swap sign of result */ + res= -res; } for (end= a + a_length-length; a < end ; a++) { @@ -683,8 +690,14 @@ my_bool my_like_range_tis620(CHARSET_INFO *cs __attribute__((unused)), } if (*ptr == w_many) /* '%' in SQL */ { - *min_length= (uint) (min_str - min_org); - *max_length=res_length; + /* + Calculate length of keys: + 'a\0\0... is the smallest possible string when we have space expand + a\ff\ff... is the biggest possible string + */ + *min_length= ((cs->state & MY_CS_BINSORT) ? (uint) (min_str - min_org) : + res_length); + *max_length= res_length; do { *min_str++ = 0; @@ -694,10 +707,10 @@ my_bool my_like_range_tis620(CHARSET_INFO *cs __attribute__((unused)), } *min_str++= *max_str++ = *ptr; } - *min_length= *max_length = (uint) (min_str - min_org); + *min_length= *max_length = (uint) (min_str - min_org); while (min_str != min_end) - *min_str++ = *max_str++ = ' '; /* Because of key compression */ + *min_str++= *max_str++ = ' '; /* Because of key compression */ return 0; } diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index 89c876ad10c..fb44a56ef0f 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -7048,6 +7048,9 @@ static int my_strnncoll_uca(CHARSET_INFO *cs, slen First string length t Second string tlen Seconf string length + diff_if_only_endspace_difference + Set to 1 if the strings should be regarded as different + if they only difference in end space NOTES: Works exactly the same with my_strnncoll_uca(), @@ -7085,13 +7088,16 @@ static int my_strnncoll_uca(CHARSET_INFO *cs, static int my_strnncollsp_uca(CHARSET_INFO *cs, my_uca_scanner_handler *scanner_handler, const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference) { - my_uca_scanner sscanner; - my_uca_scanner tscanner; - int s_res; - int t_res; + my_uca_scanner sscanner, tscanner; + int s_res, t_res; +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif + scanner_handler->init(&sscanner, cs, s, slen); scanner_handler->init(&tscanner, cs, t, tlen); @@ -7113,7 +7119,7 @@ static int my_strnncollsp_uca(CHARSET_INFO *cs, return (s_res - t_res); s_res= scanner_handler->next(&sscanner); } while (s_res > 0); - return 0; + return diff_if_only_endspace_difference ? 1 : 0; } if (s_res < 0 && t_res > 0) @@ -7128,7 +7134,7 @@ static int my_strnncollsp_uca(CHARSET_INFO *cs, return (s_res - t_res); t_res= scanner_handler->next(&tscanner); } while (t_res > 0); - return 0; + return diff_if_only_endspace_difference ? -1 : 0; } return ( s_res - t_res ); @@ -7941,11 +7947,13 @@ static int my_strnncoll_any_uca(CHARSET_INFO *cs, } static int my_strnncollsp_any_uca(CHARSET_INFO *cs, - const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *s, uint slen, + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference) { return my_strnncollsp_uca(cs, &my_any_uca_scanner_handler, - s, slen, t, tlen); + s, slen, t, tlen, + diff_if_only_endspace_difference); } static void my_hash_sort_any_uca(CHARSET_INFO *cs, @@ -7978,11 +7986,13 @@ static int my_strnncoll_ucs2_uca(CHARSET_INFO *cs, } static int my_strnncollsp_ucs2_uca(CHARSET_INFO *cs, - const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *s, uint slen, + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference) { return my_strnncollsp_uca(cs, &my_ucs2_uca_scanner_handler, - s, slen, t, tlen); + s, slen, t, tlen, + diff_if_only_endspace_difference); } static void my_hash_sort_ucs2_uca(CHARSET_INFO *cs, diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 403d31aa15b..d3fb16aa52e 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -137,6 +137,9 @@ static void my_hash_sort_ucs2(CHARSET_INFO *cs, const uchar *s, uint slen, int res; const uchar *e=s+slen; + while (e > s+1 && e[-1] == ' ' && e[-2] == '\0') + e-= 2; + while ((s < e) && (res=my_ucs2_uni(cs,&wc, (uchar *)s, (uchar*)e)) >0) { int plane = (wc>>8) & 0xFF; @@ -247,14 +250,16 @@ static int my_strnncoll_ucs2(CHARSET_INFO *cs, static int my_strnncollsp_ucs2(CHARSET_INFO *cs __attribute__((unused)), const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference + __attribute__((unused))) { const uchar *se, *te; uint minlen; /* extra safety to make sure the lengths are even numbers */ - slen= (slen >> 1) << 1; - tlen= (tlen >> 1) << 1; + slen&= ~1; + tlen&= ~1; se= s + slen; te= t + tlen; @@ -1354,8 +1359,10 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *cs, static int my_strnncollsp_ucs2_bin(CHARSET_INFO *cs, const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference) { + /* TODO: Needs to be fixed to handle end space! */ return my_strnncoll_ucs2_bin(cs,s,slen,t,tlen,0); } @@ -1444,8 +1451,14 @@ my_bool my_like_range_ucs2(CHARSET_INFO *cs, } if (ptr[0] == '\0' && ptr[1] == w_many) /* '%' in SQL */ { - *min_length= (uint) (min_str - min_org); - *max_length=res_length; + /* + Calculate length of keys: + 'a\0\0... is the smallest possible string when we have space expand + a\ff\ff... is the biggest possible string + */ + *min_length= ((cs->state & MY_CS_BINSORT) ? (uint) (min_str - min_org) : + res_length); + *max_length= res_length; do { *min_str++ = 0; *min_str++ = 0; @@ -1457,7 +1470,6 @@ my_bool my_like_range_ucs2(CHARSET_INFO *cs, *min_str++= *max_str++ = ptr[0]; *min_str++= *max_str++ = ptr[1]; } - *min_length= *max_length = (uint) (min_str - min_org); /* Temporary fix for handling w_one at end of string (key compression) */ { @@ -1469,14 +1481,16 @@ my_bool my_like_range_ucs2(CHARSET_INFO *cs, } } + *min_length= *max_length = (uint) (min_str - min_org); while (min_str + 1 < min_end) { *min_str++ = *max_str++ = '\0'; - *min_str++ = *max_str++ = ' '; /* Because if key compression */ + *min_str++ = *max_str++ = ' '; /* Because if key compression */ } return 0; } + static MY_COLLATION_HANDLER my_collation_ucs2_general_ci_handler = { NULL, /* init */ diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index ce9346eb475..ab646d36e25 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1923,12 +1923,20 @@ static void my_caseup_utf8(CHARSET_INFO *cs, char *s, uint slen) } } -static void my_hash_sort_utf8(CHARSET_INFO *cs, const uchar *s, uint slen, ulong *n1, ulong *n2) +static void my_hash_sort_utf8(CHARSET_INFO *cs, const uchar *s, uint slen, + ulong *n1, ulong *n2) { my_wc_t wc; int res; const uchar *e=s+slen; + /* + Remove end space. We have to do this to be able to compare + 'A ' and 'A' as identical + */ + while (e > s && e[-1] == ' ') + e--; + while ((s < e) && (res=my_utf8_uni(cs,&wc, (uchar *)s, (uchar*)e))>0 ) { int plane = (wc>>8) & 0xFF; @@ -2021,6 +2029,9 @@ static int my_strnncoll_utf8(CHARSET_INFO *cs, a_length Length of 'a' b Second string to compare b_length Length of 'b' + diff_if_only_endspace_difference + Set to 1 if the strings should be regarded as different + if they only difference in end space IMPLEMENTATION If one string is shorter as the other, then we space extend the other @@ -2039,13 +2050,17 @@ static int my_strnncoll_utf8(CHARSET_INFO *cs, */ static int my_strnncollsp_utf8(CHARSET_INFO *cs, - const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *s, uint slen, + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference) { - int s_res,t_res; + int s_res, t_res, res; my_wc_t s_wc,t_wc; - const uchar *se= s+slen; - const uchar *te= t+tlen; + const uchar *se= s+slen, *te= t+tlen; + +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif while ( s < se && t < te ) { @@ -2074,16 +2089,20 @@ static int my_strnncollsp_utf8(CHARSET_INFO *cs, slen= se-s; tlen= te-t; + res= 0; if (slen != tlen) { int swap= 0; + if (diff_if_only_endspace_difference) + res= 1; /* Assume 'a' is bigger */ if (slen < tlen) { slen= tlen; s= t; se= te; swap= -1; + res= -res; } /* This following loop uses the fact that in UTF-8 @@ -2101,7 +2120,7 @@ static int my_strnncollsp_utf8(CHARSET_INFO *cs, return ((int)*s - (int) ' ') ^ swap; } } - return 0; + return res; } diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 4ada3d47bf5..896aef775cf 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -479,7 +479,8 @@ static int my_strnncoll_win1250ch(CHARSET_INFO *cs __attribute__((unused)), static int my_strnncollsp_win1250ch(CHARSET_INFO * cs, const uchar *s, uint slen, - const uchar *t, uint tlen) + const uchar *t, uint tlen, + my_bool diff_if_only_endspace_difference) { for ( ; slen && s[slen-1] == ' ' ; slen--); for ( ; tlen && t[tlen-1] == ' ' ; tlen--); @@ -594,11 +595,19 @@ my_like_range_win1250ch(CHARSET_INFO *cs __attribute__((unused)), if (*min_str != min_sort_char) only_min_found= 0; min_str++; - *max_str++ = like_range_prefix_max_win1250ch[(uint)(*ptr)]; + *max_str++= like_range_prefix_max_win1250ch[(uint)(*ptr)]; } - *min_length = (uint) (min_str - min_org); - *max_length = res_length; + if (cs->state & MY_CS_BINSORT) + *min_length= (uint) (min_str - min_org); + else + { + /* 'a\0\0... is the smallest possible string */ + *min_length= res_length; + } + /* a\ff\ff... is the biggest possible string */ + *max_length= res_length; + while (min_str != min_end) { *min_str++ = min_sort_char; diff --git a/strings/decimal.c b/strings/decimal.c index 2dcc2c88ceb..c691bcb62fc 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -98,10 +98,12 @@ implementation-defined. */ -#include <decimal.h> +#include <my_global.h> #include <m_ctype.h> #include <myisampack.h> #include <my_sys.h> /* for my_alloca */ +#include <m_string.h> +#include <decimal.h> typedef decimal_digit dec1; typedef longlong dec2; @@ -308,7 +310,7 @@ static int str2dec(char *from, decimal *to, char **end, my_bool fixed) char *s=from, *s1; int i, intg, frac, error, intg1, frac1; dec1 x,*buf; - + LINT_INIT(error); sanity(to); while (my_isspace(&my_charset_latin1, *s)) @@ -366,6 +368,7 @@ static int str2dec(char *from, decimal *to, char **end, my_bool fixed) intg=intg1*DIG_PER_DEC1; } } + /* Error is guranteed to be set here */ to->intg=intg; to->frac=frac; @@ -1354,6 +1357,8 @@ static int do_div_mod(decimal *from1, decimal *from2, *start2, *stop2, *stop1, *stop0, norm2, carry, *start1; dec2 norm_factor, x, guess, y; + LINT_INIT(error); + if (mod) to=mod; |