summaryrefslogtreecommitdiff
path: root/strings
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2004-12-06 02:00:37 +0200
committerunknown <monty@mysql.com>2004-12-06 02:00:37 +0200
commite04e1dd2889a3feec2fe04fc0b68594372ba32e8 (patch)
treeb75e098b12b8e91a3470008602bacbb5b3009e45 /strings
parent0b4dfe8b55bd9fa6e87c01d151639d717def6450 (diff)
downloadmariadb-git-e04e1dd2889a3feec2fe04fc0b68594372ba32e8.tar.gz
Add support for up to VARCHAR (size up to 65535)
Renamed HA_VAR_LENGTH to HA_VAR_LENGTH_PART Renamed in all files FIELD_TYPE_STRING and FIELD_TYPE_VAR_STRING to MYSQL_TYPE_STRING and MYSQL_TYPE_VAR_STRING to make it easy to catch all possible errors Added support for VARCHAR KEYS to heap Removed support for ISAM Now only long VARCHAR columns are changed to TEXT on demand (not CHAR) Internal temporary files can now use fixed length tables if the used VARCHAR columns are short BitKeeper/deleted/.del-ha_isam.cc~4dce65904db2675e: Delete: sql/ha_isam.cc BitKeeper/deleted/.del-_cache.c~b5d80b5c3ae233b1: Delete: isam/_cache.c BitKeeper/deleted/.del-_dbug.c~88d7964ae5e3c9bd: Delete: isam/_dbug.c BitKeeper/deleted/.del-_dynrec.c~48dd758f5a5450df: Delete: isam/_dynrec.c BitKeeper/deleted/.del-_key.c~ce62d47a6c681084: Delete: isam/_key.c BitKeeper/deleted/.del-_locking.c~dea4cdc6ea425c67: Delete: isam/_locking.c BitKeeper/deleted/.del-_packrec.c~47ae1b16c007e9be: Delete: isam/_packrec.c BitKeeper/deleted/.del-_page.c~148b1a613d052ee8: Delete: isam/_page.c BitKeeper/deleted/.del-_search.c~f509292aa1ff18ff: Delete: isam/_search.c BitKeeper/deleted/.del-_statrec.c~58d9263b3475d58b: Delete: isam/_statrec.c BitKeeper/deleted/.del-changed.c~d075de80a314b02d: Delete: isam/changed.c BitKeeper/deleted/.del-close.c~fd62629496ee5bcc: Delete: isam/close.c BitKeeper/deleted/.del-create.c~96cecc433c0c2242: Delete: isam/create.c BitKeeper/deleted/.del-delete.c~65ee8daaa75a14b6: Delete: isam/delete.c BitKeeper/deleted/.del-extra.c~706f29d72beb2565: Delete: isam/extra.c BitKeeper/deleted/.del-info.c~96cfb747af8da0d: Delete: isam/info.c BitKeeper/deleted/.del-isamchk.c~c0f59c2687d2248f: Delete: isam/isamchk.c BitKeeper/deleted/.del-isamlog.c~85b6b31c6e2b8519: Delete: isam/isamlog.c BitKeeper/deleted/.del-log.c~55a973013d55cade: Delete: isam/log.c BitKeeper/deleted/.del-open.c~95b3b75042fae00a: Delete: isam/open.c BitKeeper/deleted/.del-pack_isam.c~43801f0df7504834: Delete: isam/pack_isam.c BitKeeper/deleted/.del-panic.c~f7fd71605324f8f3: Delete: isam/panic.c BitKeeper/deleted/.del-range.c~142f1f8ac4948082: Delete: isam/range.c BitKeeper/deleted/.del-rfirst.c~66f494291dc005d3: Delete: isam/rfirst.c BitKeeper/deleted/.del-rkey.c~cc54c6498352f999: Delete: isam/rkey.c BitKeeper/deleted/.del-rlast.c~d1fe1866139e9866: Delete: isam/rlast.c BitKeeper/deleted/.del-rnext.c~b308eaa1e11ea7de: Delete: isam/rnext.c BitKeeper/deleted/.del-rprev.c~b359f71fdea4bbce: Delete: isam/rprev.c BitKeeper/deleted/.del-rrnd.c~7fcfcce88d4a5200: Delete: isam/rrnd.c BitKeeper/deleted/.del-rsame.c~75a62d5548103a15: Delete: isam/rsame.c BitKeeper/deleted/.del-rsamepos.c~5b5652dd2cda6d5d: Delete: isam/rsamepos.c BitKeeper/deleted/.del-sort.c~e2e56b5a37ce86f4: Delete: isam/sort.c BitKeeper/deleted/.del-static.c~3a1354b84f4a9cc7: Delete: isam/static.c BitKeeper/deleted/.del-test1.c~64d52e9412d457ed: Delete: isam/test1.c BitKeeper/deleted/.del-test2.c~2f9a632cab572958: Delete: isam/test2.c BitKeeper/deleted/.del-test3.c~e8a7a4afe8a087: Delete: isam/test3.c BitKeeper/deleted/.del-isamdef.h~ac8d49e7e2201c66: Delete: isam/isamdef.h BitKeeper/deleted/.del-update.c~670264f51dc44934: Delete: isam/update.c BitKeeper/deleted/.del-write.c~8f1918b1f6770e54: Delete: isam/write.c BitKeeper/deleted/.del-Makefile.am~6cfa0db5e7778d09: Delete: isam/Makefile.am BitKeeper/deleted/.del-make-ccc~3ee55391eda0b0ab: Delete: isam/make-ccc BitKeeper/deleted/.del-ChangeLog~208984fb7a51e568: Delete: isam/ChangeLog BitKeeper/deleted/.del-test_all.res~c2aafb49a3a77db7: Delete: isam/test_all.res BitKeeper/deleted/.del-test_all~93c701e44a9c5b65: Delete: isam/test_all BitKeeper/deleted/.del-.cvsignore~54f6f0f2d5012561: Delete: isam/.cvsignore BitKeeper/deleted/.del-ha_isammrg.cc~dc682e4755d77a2e: Delete: sql/ha_isammrg.cc BitKeeper/deleted/.del-ha_isam.h~bf53d533be3d3927: Delete: sql/ha_isam.h BitKeeper/deleted/.del-ha_isammrg.h~66fd2e5bfe7207dc: Delete: sql/ha_isammrg.h acinclude.m4: Remove ISAM client/mysqldump.c: FIELD_TYPE -> MYSQL_TYPE client/mysqltest.c: Add missing DBUG_RETURN configure.in: Remove ISAM heap/heapdef.h: Add support for VARCHAR heap/hp_create.c: Add support for VARCHAR heap/hp_delete.c: Add support for VARCHAR heap/hp_hash.c: Add support for VARCHAR (VARCHAR keys was not supported before) heap/hp_rkey.c: Add support for VARCHAR heap/hp_update.c: Add support for VARCHAR heap/hp_write.c: Add support for VARCHAR (Added flag SEARCH_UPDATE to mark that this is an update) include/decimal.h: Remove not needed my_global.h include/m_ctype.h: Add support for VARCHAR include/my_base.h: Add support for VARCHAR include/my_handler.h: Moved general purpose macro from MyISAM code include/mysql_com.h: Add support for VARCHAR libmysql/libmysql.c: Add support for VARCHAR libmysqld/Makefile.am: Removed ISAM myisam/ft_static.c: Add support for VARCHAR myisam/ft_test1.c: Add support for VARCHAR myisam/ft_update.c: Add support for VARCHAR myisam/mi_check.c: Add support for VARCHAR myisam/mi_create.c: Add support for VARCHAR - VARCHAR key segments are marked with HA_VAR_LENGTH_PART myisam/mi_key.c: Add support for VARCHAR Fixed bug in old VARCHAR code when reading index-only myisam/mi_range.c: Fixed comment style myisam/mi_rnext_same.c: Handle case where equal keys can be of different length myisam/mi_search.c: Add support for VARCHAR myisam/mi_test1.c: Add support for VARCHAR myisam/mi_unique.c: Add support for VARCHAR (Some new code to handle keys that are equal but have different lengths) myisam/mi_write.c: Fixed comment myisam/myisamchk.c: Better infotext if wrong type mysql-test/r/bdb.result: Updated old result and new results for VARCHAR mysql-test/r/create.result: Updated old result and new results for VARCHAR mysql-test/r/ctype_tis620.result: Updated old result and new results for VARCHAR (Old code sorted tis620 wrong) mysql-test/r/ctype_ucs.result: Updated old result and new results for VARCHAR mysql-test/r/endspace.result: Updated old result and new results for VARCHAR mysql-test/r/func_like.result: Updated old result and new results for VARCHAR mysql-test/r/heap.result: Updated old result and new results for VARCHAR mysql-test/r/innodb.result: Updated old result. This will change a bit when also InnoDB supports VARCHAR mysql-test/r/merge.result: Updated old result and new results for VARCHAR mysql-test/r/myisam.result: Updated old result and new results for VARCHAR mysql-test/r/mysqldump.result: Updated old result and new results for VARCHAR mysql-test/r/order_by.result: Updated old result and new results for VARCHAR (Key length is different for VARCHAR) mysql-test/r/ps.result: Updated old result and new results for VARCHAR mysql-test/r/ps_1general.result: Updated results for new .frm version Don't print seconds in show full process list as this may change mysql-test/r/ps_2myisam.result: Updated old result and new results for VARCHAR mysql-test/r/ps_3innodb.result: Updated old result and new results for VARCHAR mysql-test/r/ps_4heap.result: Updated old result and new results for VARCHAR mysql-test/r/ps_5merge.result: Updated old result and new results for VARCHAR mysql-test/r/ps_6bdb.result: Updated old result and new results for VARCHAR mysql-test/r/select.result.es: Updated results by hand mysql-test/r/select.result: Updated old result and new results for VARCHAR mysql-test/r/select_found.result: Updated old result and new results for VARCHAR mysql-test/r/show_check.result: Updated old result and new results for VARCHAR mysql-test/r/strict.result: Updated old result and new results for VARCHAR mysql-test/r/subselect.result: Updated old result and new results for VARCHAR mysql-test/r/system_mysql_db.result: Updated old result and new results for VARCHAR mysql-test/r/type_blob.result: Updated old result and new results for VARCHAR mysql-test/r/type_ranges.result: Updated old result and new results for VARCHAR mysql-test/r/type_ranges.result.es: Updated some results by hand mysql-test/t/bdb.test: Test VARCHAR mysql-test/t/ctype_ucs.test: Some fixes related to VARCHAR mysql-test/t/endspace.test: Fixes to make it easier to compare columns with end space mysql-test/t/heap.test: Test VARCHAR mysql-test/t/innodb.test: Prepare for testing VARCHAR mysql-test/t/myisam.test: Test VARCHAR mysql-test/t/ps_1general.test: Don't show seconds for show processlist mysql-test/t/ps_4heap.test: Update for VARCHAR mysql-test/t/strict.test: Fix test for VARCHAR mysql-test/t/type_blob.test: Update test for VARCHAR Note that now you can't store 'a' and 'a ' in an unique varchar/text index if the column is not binary mysys/my_handler.c: Add support for VARCHAR ndb/src/common/util/NdbSqlUtil.cpp: Fix for usage of strnncollsp scripts/mysql_fix_privilege_tables.sh: Simple fix so that my_print_defaults works sql/Makefile.am: Remove ISAM sql/field.cc: Add support for VARCHAR Fixed the keys for blob's are compared with strnncollsp Ensure that old tables from MySQL 4.0 works as they did before. (Old VARCHAR will be converted to new VARCHAR on ALTER TABLE) sql/field.h: Add support for VARCHAR sql/field_conv.cc: Change FIELD_TYPE_VAR_STRING -> MYSQL_TYPE_VARCHAR Added usage of HA_KEY_BLOB_LENGTH sql/ha_berkeley.cc: Add support for VARCHAR Added usage of table->insert_or_update if we would ever want to know in key_cmp if we are changing keys sql/ha_heap.cc: Add support for VARCHAR sql/ha_innodb.cc: Changed MYSQL_TYPE_VAR_STRING to MYSQL_TYPE_VARCHAR. Waiting for Heikki to add full VARCHAR support sql/ha_innodb.h: InnoDB doesn't support full VARCHAR yet sql/ha_myisam.cc: Add support for VARCHAR sql/ha_ndbcluster.cc: Add support for VARCHAR sql/handler.h: Added HA_NO_VARCHAR for table handler that doesn't support VARCHAR. In this case MySQL will create a normal CHAR instead sql/item.cc: Fixed access of already freed memory Added support of VARCHAR - varchar length is now checked in mysql_prepare sql/item_cmpfunc.cc: Added new parameter to strncollsp sql/item_sum.cc: Added new parameter to strncollsp FIELD_TYPE -> MYSQL_TYPE sql/key.cc: Add support for VARCHAR sql/opt_range.cc: Remove character set parameter from set_key_image() sql/opt_sum.cc: Remove character set parameter from set_key_image() sql/protocol.cc: Return MYSQL_TYPE_VAR_STRING instead of MYSQL_TYPE_VARCHAR to clients (to not cause compatiblity problems) sql/sql_acl.cc: Change key handling code so that we can use CHAR or VARCHAR for the user table columns sql/sql_base.cc: Remove old, not used code sql/sql_help.cc: Remove charset from get_key_image sql/sql_parse.cc: Ensure that OPTION_TABLE_LOCK is cleared ASAP; This fixed a problem in BDB transaction code when one used LOCK TABLES on a BDB table Added support for VARCHAR Moved field length checking and VARCHAR -> TEXT convert to mysql_prepare (as we need the know the character set for the column) sql/sql_select.cc: Added support of VARCHAR Added heuristic to use fixed size rows for tmp tables if we are using only a few short VARCHAR's sql/sql_string.cc: Added extra argument to strnncollsp sql/sql_table.cc: Add support for VARCHAR Automaticly convert (with warning) big VARCHAR (but not CHAR) to TEXT If handler doesn't support VARCHAR convert VARCHAR to CHAR sql/sql_update.cc: Fixed compiler warning sql/sql_yacc.yy: Add support for VARCHAR sql/strfunc.cc: Fixed valgrind warning sql/structs.h: Added 'table' to KEY structure to make life easier for some handler functions sql/table.cc: Add support for VARCHAR - New .frm version - FIELD_TYPE -> MYSQL_TYPE sql/table.h: Added insert_or_update; A bool flag a handler can set/reset if needed (for handler internal usage) sql/unireg.h: Add support for VARCHAR strings/ctype-big5.c: Added new argument to strnncollsp() to allow one to define if end space are significant or not Changed my_like_range... to correctly calculate min_length & max_length strings/ctype-bin.c: Added new argument to strnncollsp() to allow one to define if end space are significant or not strings/ctype-czech.c: Changed my_like_range... to correctly calculate min_length & max_length strings/ctype-gbk.c: Added new argument to strnncollsp() to allow one to define if end space are significant or not Changed my_like_range... to correctly calculate min_length & max_length strings/ctype-latin1.c: Added new argument to strnncollsp() to allow one to define if end space are significant or not strings/ctype-mb.c: Added new argument to strnncollsp() to allow one to define if end space are significant or not Changed my_like_range... to correctly calculate min_length & max_length strings/ctype-simple.c: Added new argument to strnncollsp() to allow one to define if end space are significant or not Changed my_like_range... to correctly calculate min_length & max_length strings/ctype-sjis.c: Added new argument to strnncollsp() to allow one to define if end space are significant or not Changed my_like_range... to correctly calculate min_length & max_length strings/ctype-tis620.c: Added new argument to strnncollsp() to allow one to define if end space are significant or not Changed my_like_range... to correctly calculate min_length & max_length strings/ctype-uca.c: Added new argument to strnncollsp() to allow one to define if end space are significant or not strings/ctype-ucs2.c: Changed my_like_range... to correctly calculate min_length & max_length strings/ctype-utf8.c: Added new argument to strnncollsp() to allow one to define if end space are significant or not strings/ctype-win1250ch.c: Changed my_like_range... to correctly calculate min_length & max_length strings/decimal.c: Fixed include files usage Fixed some compiler warnings tests/client_test.c: Ensure tests works with VARCHAR
Diffstat (limited to 'strings')
-rw-r--r--strings/ctype-big5.c36
-rw-r--r--strings/ctype-bin.c21
-rw-r--r--strings/ctype-czech.c18
-rw-r--r--strings/ctype-gbk.c27
-rw-r--r--strings/ctype-latin1.c17
-rw-r--r--strings/ctype-mb.c34
-rw-r--r--strings/ctype-simple.c40
-rw-r--r--strings/ctype-sjis.c31
-rw-r--r--strings/ctype-tis620.c32
-rw-r--r--strings/ctype-uca.c36
-rw-r--r--strings/ctype-ucs2.c26
-rw-r--r--strings/ctype-utf8.c33
-rw-r--r--strings/ctype-win1250ch.c17
-rw-r--r--strings/decimal.c9
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 6f9e9f74d35..433614141ba 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 7d81766c4cb..adc7db00139 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;
}
@@ -489,9 +502,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);
- *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;
+ /* Create min key */
do
{
*min_str++= (char) cs->min_sort_char;
@@ -527,13 +546,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++ = *max_str++ = ' '; /* Because if key compression */
+ *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 a2ba4783591..b294dc7150f 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,13 +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;
+ uchar buf[80], *end, *a, *b;
uint length;
- int res= 0;
- int alloced= 0;
+ int res= 0, alloced= 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))
@@ -594,6 +597,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.
@@ -604,6 +609,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++)
{
@@ -687,8 +693,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;
@@ -698,10 +710,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 91af7af0c54..978f249a028 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 );
@@ -7939,11 +7945,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,
@@ -7976,11 +7984,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 851c2044f47..dc558839a1b 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;
@@ -220,8 +223,10 @@ static int my_strnncoll_ucs2(CHARSET_INFO *cs,
static int my_strnncollsp_ucs2(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(cs,s,slen,t,tlen,0);
}
@@ -1287,8 +1292,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);
}
@@ -1377,8 +1384,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;
@@ -1390,7 +1403,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) */
{
@@ -1402,14 +1414,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 b3097649158..f7b6fe5e961 100644
--- a/strings/ctype-utf8.c
+++ b/strings/ctype-utf8.c
@@ -1921,12 +1921,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;
@@ -2019,6 +2027,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
@@ -2037,13 +2048,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 )
{
@@ -2072,16 +2087,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
@@ -2099,7 +2118,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 b4dbda3e8ed..3be77f97eff 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 3d3ddc36116..8ac08a98c08 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;
@@ -1310,6 +1313,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;