summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--acinclude.m41
-rw-r--r--client/mysqltest.c19
-rw-r--r--configure.in28
-rw-r--r--include/m_ctype.h6
-rw-r--r--myisam/ft_boolean_search.c38
-rw-r--r--myisam/mi_check.c10
-rw-r--r--mysql-test/Makefile.am2
-rw-r--r--mysql-test/mysql-test-run.sh1
-rw-r--r--mysql-test/r/fulltext.result11
-rw-r--r--mysql-test/t/fulltext.test9
-rw-r--r--mysql-test/t/rpl000015.test2
-rw-r--r--mysys/my_handler.c4
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--strings/ctype-big5.c5
-rw-r--r--strings/ctype-bin.c18
-rw-r--r--strings/ctype-czech.c8
-rw-r--r--strings/ctype-gbk.c5
-rw-r--r--strings/ctype-latin1.c5
-rw-r--r--strings/ctype-mb.c19
-rw-r--r--strings/ctype-simple.c7
-rw-r--r--strings/ctype-sjis.c5
-rw-r--r--strings/ctype-tis620.c6
-rw-r--r--strings/ctype-uca.c5
-rw-r--r--strings/ctype-ucs2.c30
-rw-r--r--strings/ctype-utf8.c5
-rw-r--r--strings/ctype-win1250ch.c15
26 files changed, 181 insertions, 85 deletions
diff --git a/acinclude.m4 b/acinclude.m4
index baad145c0e0..7c0e8890b95 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -1452,6 +1452,7 @@ AC_DEFUN([MYSQL_CHECK_NDBCLUSTER], [
;;
esac
+ AM_CONDITIONAL(HAVE_NDBCLUSTER_DB, test "have_ndbcluster" = "yes")
AC_SUBST(ndbcluster_includes)
AC_SUBST(ndbcluster_libs)
AC_SUBST(ndbcluster_system_libs)
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 830846eda84..f638053b515 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -318,6 +318,7 @@ TYPELIB command_typelib= {array_elements(command_names),"",
DYNAMIC_STRING ds_res;
static void die(const char *fmt, ...);
static void init_var_hash();
+static VAR* var_from_env(const char *, const char *);
static byte* get_var_key(const byte* rec, uint* len,
my_bool __attribute__((unused)) t);
static VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
@@ -654,11 +655,10 @@ VAR* var_get(const char* var_name, const char** var_name_end, my_bool raw,
if (!(v = (VAR*) hash_search(&var_hash, save_var_name,
var_name - save_var_name)))
{
- if (ignore_not_existing)
- DBUG_RETURN(0);
- if (end)
- *(char*) end = 0;
- die("Variable '%s' used uninitialized", save_var_name);
+ char c=*var_name, *s=(char*)var_name;;
+ *s=0;
+ v=var_from_env(save_var_name, "");
+ *s=c;
}
--var_name; /* Point at last character */
}
@@ -2580,7 +2580,7 @@ static void var_free(void *v)
}
-static void var_from_env(const char *name, const char *def_val)
+static VAR* var_from_env(const char *name, const char *def_val)
{
const char *tmp;
VAR *v;
@@ -2589,6 +2589,7 @@ static void var_from_env(const char *name, const char *def_val)
v = var_init(0, name, 0, tmp, 0);
my_hash_insert(&var_hash, (byte*)v);
+ return v;
}
@@ -2599,10 +2600,8 @@ static void init_var_hash(MYSQL *mysql)
if (hash_init(&var_hash, charset_info,
1024, 0, 0, get_var_key, var_free, MYF(0)))
die("Variable hash initialization failed");
- var_from_env("MASTER_MYPORT", "9306");
- var_from_env("SLAVE_MYPORT", "9307");
- var_from_env("MYSQL_TEST_DIR", "/tmp");
- var_from_env("BIG_TEST", opt_big_test ? "1" : "0");
+ if (opt_big_test)
+ my_hash_insert(&var_hash, (byte*) var_init(0,"BIG_TEST", 0, "1",0));
v= var_init(0,"MAX_TABLES", 0, (sizeof(ulong) == 4) ? "31" : "62",0);
my_hash_insert(&var_hash, (byte*) v);
v= var_init(0,"SERVER_VERSION", 0, mysql_get_server_info(mysql), 0);
diff --git a/configure.in b/configure.in
index be40d8ff029..c1e3f9ff961 100644
--- a/configure.in
+++ b/configure.in
@@ -2905,7 +2905,6 @@ then
NDB_DEFS="-DNDEBUG"
CXXFLAGS="$CXXFLAGS \$(NDB_CXXFLAGS) \$(NDB_CXXFLAGS_LOC) \$(NDB_CXXFLAGS_RELEASE_LOC)"
fi
-fi
AC_SUBST([NDB_DEFS])
@@ -2928,14 +2927,9 @@ then
fi
AC_SUBST([ndb_bin_am_ldflags])
AC_SUBST([ndb_opt_test_subdirs])
-
-AC_SUBST(MAKE_BINARY_DISTRIBUTION_OPTIONS)
-
-# Output results
-AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile dnl
- ndb/docs/Makefile dnl
- ndb/Makefile ndb/include/Makefile dnl
+AC_CONFIG_FILES(ndb/Makefile ndb/include/Makefile dnl
ndb/src/Makefile ndb/src/common/Makefile dnl
+ ndb/docs/Makefile dnl
ndb/tools/Makefile dnl
ndb/src/common/debugger/Makefile ndb/src/common/debugger/signaldata/Makefile dnl
ndb/src/common/portlib/Makefile dnl
@@ -2976,7 +2970,14 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile dnl
ndb/test/ndbapi/Makefile dnl
ndb/test/ndbapi/bank/Makefile dnl
ndb/test/tools/Makefile dnl
- ndb/test/run-test/Makefile dnl
+ ndb/test/run-test/Makefile mysql-test/ndb/Makefile dnl
+ )
+fi
+
+AC_SUBST(MAKE_BINARY_DISTRIBUTION_OPTIONS)
+
+# Output results
+AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile isam/Makefile dnl
strings/Makefile regex/Makefile heap/Makefile dnl
bdb/Makefile dnl
myisam/Makefile myisammrg/Makefile dnl
@@ -2989,15 +2990,14 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile dnl
merge/Makefile dbug/Makefile scripts/Makefile dnl
include/Makefile sql-bench/Makefile tools/Makefile dnl
tests/Makefile Docs/Makefile support-files/Makefile dnl
- support-files/MacOSX/Makefile mysql-test/Makefile mysql-test/ndb/Makefile dnl
+ support-files/MacOSX/Makefile mysql-test/Makefile dnl
netware/Makefile dnl
include/mysql_version.h dnl
cmd-line-utils/Makefile dnl
cmd-line-utils/libedit/Makefile dnl
- cmd-line-utils/readline/Makefile dnl
- , , [
- test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
- ])
+ cmd-line-utils/readline/Makefile)
+ AC_CONFIG_COMMANDS([default], , test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h)
+ AC_OUTPUT
rm -f $AVAILABLE_LANGUAGES_ERRORS_RULES
echo
diff --git a/include/m_ctype.h b/include/m_ctype.h
index 9be5538b48a..e5eb54295a8 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -104,7 +104,7 @@ typedef struct my_collation_handler_st
my_bool (*init)(struct charset_info_st *, void *(*alloc)(uint));
/* Collation routines */
int (*strnncoll)(struct charset_info_st *,
- const uchar *, uint, const uchar *, uint);
+ const uchar *, uint, const uchar *, uint, my_bool);
int (*strnncollsp)(struct charset_info_st *,
const uchar *, uint, const uchar *, uint);
int (*strnxfrm)(struct charset_info_st *,
@@ -253,7 +253,7 @@ extern CHARSET_INFO my_charset_cp1250_czech_ci;
extern int my_strnxfrm_simple(CHARSET_INFO *, uchar *, uint, const uchar *,
uint);
extern int my_strnncoll_simple(CHARSET_INFO *, const uchar *, uint,
- const uchar *, uint);
+ const uchar *, uint, my_bool);
extern int my_strnncollsp_simple(CHARSET_INFO *, const uchar *, uint,
const uchar *, uint);
@@ -387,7 +387,7 @@ extern my_bool my_parse_charset_xml(const char *bug, uint len,
#define my_binary_compare(s) ((s)->state & MY_CS_BINSORT)
#define use_strnxfrm(s) ((s)->state & MY_CS_STRNXFRM)
#define my_strnxfrm(s, a, b, c, d) ((s)->coll->strnxfrm((s), (a), (b), (c), (d)))
-#define my_strnncoll(s, a, b, c, d) ((s)->coll->strnncoll((s), (a), (b), (c), (d)))
+#define my_strnncoll(s, a, b, c, d) ((s)->coll->strnncoll((s), (a), (b), (c), (d), 0))
#define my_like_range(s, a, b, c, d, e, f, g, h, i, j) \
((s)->coll->like_range((s), (a), (b), (c), (d), (e), (f), (g), (h), (i), (j)))
#define my_wildcmp(cs,s,se,w,we,e,o,m) ((cs)->coll->wildcmp((cs),(s),(se),(w),(we),(e),(o),(m)))
diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c
index 345cd3ceb0c..cac4d08f5d6 100644
--- a/myisam/ft_boolean_search.c
+++ b/myisam/ft_boolean_search.c
@@ -53,10 +53,10 @@ static double _nwghts[11]=
-3.796875000000000};
static double *nwghts=_nwghts+5; /* nwghts[i] = -0.5*1.5**i */
-#define FTB_FLAG_TRUNC 1 /* MUST be 1 */
+#define FTB_FLAG_TRUNC 1 /* */
#define FTB_FLAG_YES 2 /* no two from these three */
#define FTB_FLAG_NO 4 /* YES, NO, WONLY */
-#define FTB_FLAG_WONLY 8 /* should be ever set both */
+#define FTB_FLAG_WONLY 8 /* should be _ever_ set both */
typedef struct st_ftb_expr FTB_EXPR;
struct st_ftb_expr
@@ -157,6 +157,7 @@ static void _ftb_parse_query(FTB *ftb, byte **start, byte *end,
w.len+extra));
ftbw->len=w.len+1;
ftbw->flags=0;
+ ftbw->off=0;
if (param.yesno>0) ftbw->flags|=FTB_FLAG_YES;
if (param.yesno<0) ftbw->flags|=FTB_FLAG_NO;
if (param.trunc) ftbw->flags|=FTB_FLAG_TRUNC;
@@ -203,23 +204,26 @@ static int _ftb_no_dupes_cmp(void* not_used __attribute__((unused)),
static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
{
int r;
- uint off;
int subkeys=1;
my_bool can_go_down;
MI_INFO *info=ftb->info;
+ uint off, extra=HA_FT_WLEN+info->s->base.rec_reflength;
+ byte *lastkey_buf=ftbw->word+ftbw->off;
+
+ if (ftbw->flags & FTB_FLAG_TRUNC)
+ lastkey_buf+=ftbw->len;
if (init_search)
{
ftbw->key_root=info->s->state.key_root[ftb->keynr];
ftbw->keyinfo=info->s->keyinfo+ftb->keynr;
- ftbw->off=0;
r=_mi_search(info, ftbw->keyinfo, (uchar*) ftbw->word, ftbw->len,
SEARCH_FIND | SEARCH_BIGGER, ftbw->key_root);
}
else
{
- r=_mi_search(info, ftbw->keyinfo, (uchar*) ftbw->word+ftbw->off,
+ r=_mi_search(info, ftbw->keyinfo, (uchar*) lastkey_buf,
USE_WHOLE_KEY, SEARCH_BIGGER, ftbw->key_root);
}
@@ -230,7 +234,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
if (can_go_down)
{
/* going down ? */
- off=info->lastkey_length-HA_FT_WLEN-info->s->base.rec_reflength;
+ off=info->lastkey_length-extra;
subkeys=ft_sintXkorr(info->lastkey+off);
}
if (subkeys<0 || info->lastpos < info->state->data_file_length)
@@ -243,11 +247,11 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
if (!r && !ftbw->off)
{
r= mi_compare_text(ftb->charset,
- info->lastkey + (ftbw->flags & FTB_FLAG_TRUNC),
- ftbw->len - (ftbw->flags & FTB_FLAG_TRUNC),
- (uchar*) ftbw->word + (ftbw->flags & FTB_FLAG_TRUNC),
- ftbw->len - (ftbw->flags & FTB_FLAG_TRUNC),
- 0,0);
+ info->lastkey+1,
+ info->lastkey_length-extra-1,
+ (uchar*) ftbw->word+1,
+ ftbw->len-1,
+ (my_bool) (ftbw->flags & FTB_FLAG_TRUNC),0);
}
if (r) /* not found */
@@ -269,8 +273,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
}
/* going up to the first-level tree to continue search there */
- _mi_dpointer(info, (uchar*) (ftbw->word+ftbw->off+HA_FT_WLEN),
- ftbw->key_root);
+ _mi_dpointer(info, (uchar*) (lastkey_buf+HA_FT_WLEN), ftbw->key_root);
ftbw->key_root=info->s->state.key_root[ftb->keynr];
ftbw->keyinfo=info->s->keyinfo+ftb->keynr;
ftbw->off=0;
@@ -278,7 +281,10 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
}
/* matching key found */
- memcpy(ftbw->word+ftbw->off, info->lastkey, info->lastkey_length);
+ memcpy(lastkey_buf, info->lastkey, info->lastkey_length);
+ if (lastkey_buf == ftbw->word)
+ ftbw->len=info->lastkey_length-extra;
+
/* going down ? */
if (subkeys<0)
{
@@ -291,7 +297,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
ftbw->keyinfo=& info->s->ft2_keyinfo;
r=_mi_search_first(info, ftbw->keyinfo, ftbw->key_root);
DBUG_ASSERT(r==0); /* found something */
- memcpy(ftbw->word+off, info->lastkey, info->lastkey_length);
+ memcpy(lastkey_buf+off, info->lastkey, info->lastkey_length);
}
ftbw->docid[0]=info->lastpos;
return 0;
@@ -356,7 +362,7 @@ static void _ftb_init_index_search(FT_INFO *ftb)
else
reset_tree(& ftb->no_dupes);
}
-
+
if (_ft2_search(ftb, ftbw, 1))
return;
}
diff --git a/myisam/mi_check.c b/myisam/mi_check.c
index 6da0fd9552b..96a26fd90f1 100644
--- a/myisam/mi_check.c
+++ b/myisam/mi_check.c
@@ -142,6 +142,8 @@ int chk_del(MI_CHECK *param, register MI_INFO *info, uint test_flag)
empty=0;
for (i= info->state->del ; i > 0L && next_link != HA_OFFSET_ERROR ; i--)
{
+ if (*killed_ptr(param))
+ DBUG_RETURN(1);
if (test_flag & T_VERBOSE)
printf(" %9s",llstr(next_link,buff));
if (next_link >= info->state->data_file_length)
@@ -233,6 +235,8 @@ static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr)
records= (ha_rows) (info->state->key_file_length / block_size);
while (next_link != HA_OFFSET_ERROR && records > 0)
{
+ if (*killed_ptr(param))
+ DBUG_RETURN(1);
if (param->testflag & T_VERBOSE)
printf("%16s",llstr(next_link,llbuff));
if (next_link > info->state->key_file_length ||
@@ -372,6 +376,8 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
for (key= 0,keyinfo= &share->keyinfo[0]; key < share->base.keys ;
rec_per_key_part+=keyinfo->keysegs, key++, keyinfo++)
{
+ if (*killed_ptr(param))
+ DBUG_RETURN(-1);
param->key_crc[key]=0;
if (!(((ulonglong) 1 << key) & share->state.key_map))
{
@@ -592,6 +598,8 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
}
for ( ;; )
{
+ if (*killed_ptr(param))
+ goto err;
memcpy((char*) info->lastkey,(char*) key,key_length);
info->lastkey_length=key_length;
if (nod_flag)
@@ -782,6 +790,8 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
bzero((char*) key_checksum, info->s->base.keys * sizeof(key_checksum[0]));
while (pos < info->state->data_file_length)
{
+ if (*killed_ptr(param))
+ goto err2;
switch (info->s->data_file_type) {
case STATIC_RECORD:
if (my_b_read(&param->read_cache,(byte*) record,
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index 266cc7799b0..bebb84c11db 100644
--- a/mysql-test/Makefile.am
+++ b/mysql-test/Makefile.am
@@ -17,7 +17,9 @@
## Process this file with automake to create Makefile.in
+if HAVE_NDBCLUSTER_DB
SUBDIRS = ndb
+endif
benchdir_root= $(prefix)
testdir = $(benchdir_root)/mysql-test
diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh
index 13ddb8f221e..eaa5d0b9da3 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run.sh
@@ -16,6 +16,7 @@ USE_MANAGER=0
MY_TZ=GMT-3
TZ=$MY_TZ; export TZ # for UNIX_TIMESTAMP tests to work
LOCAL_SOCKET=@MYSQL_UNIX_ADDR@
+MYSQL_TCP_PORT=@MYSQL_TCP_PORT@; export MYSQL_TCP_PORT
# For query_cache test
case `uname` in
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index 3106602e718..d13c9a9c51c 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -363,3 +363,14 @@ SELECT t, collation(t) FROM t1 WHERE MATCH t AGAINST ('Osnabrueck');
t collation(t)
aus Osnabrück latin1_german2_ci
DROP TABLE t1;
+CREATE TABLE t1 (s varchar(255), FULLTEXT (s)) DEFAULT CHARSET=utf8;
+insert into t1 (s) values ('pära para para'),('para para para');
+select * from t1 where match(s) against('para' in boolean mode);
+s
+pära para para
+para para para
+select * from t1 where match(s) against('par*' in boolean mode);
+s
+pära para para
+para para para
+DROP TABLE t1;
diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test
index 91e81c5dbe0..66df5b1cb92 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -279,3 +279,12 @@ SELECT t, collation(t) FROM t1 WHERE MATCH t AGAINST ('Osnabrück');
SELECT t, collation(t) FROM t1 WHERE MATCH t AGAINST ('Osnabrueck');
DROP TABLE t1;
+#
+# bug#3964
+#
+
+CREATE TABLE t1 (s varchar(255), FULLTEXT (s)) DEFAULT CHARSET=utf8;
+insert into t1 (s) values ('pära para para'),('para para para');
+select * from t1 where match(s) against('para' in boolean mode);
+select * from t1 where match(s) against('par*' in boolean mode);
+DROP TABLE t1;
diff --git a/mysql-test/t/rpl000015.test b/mysql-test/t/rpl000015.test
index b0119526deb..b7fff94f7f3 100644
--- a/mysql-test/t/rpl000015.test
+++ b/mysql-test/t/rpl000015.test
@@ -12,7 +12,7 @@ show slave status;
change master to master_host='127.0.0.1';
# The following needs to be cleaned up when change master is fixed
---replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT
+--replace_result $MASTER_MYPORT MASTER_PORT $MYSQL_TCP_PORT MASTER_PORT
--replace_column 1 # 33 #
show slave status;
--replace_result $MASTER_MYPORT MASTER_PORT
diff --git a/mysys/my_handler.c b/mysys/my_handler.c
index de0fba56d21..6003808df25 100644
--- a/mysys/my_handler.c
+++ b/mysys/my_handler.c
@@ -21,13 +21,11 @@ int mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length,
uchar *b, uint b_length, my_bool part_key,
my_bool skip_end_space)
{
- if (part_key && b_length < a_length)
- a_length=b_length;
if (skip_end_space)
return charset_info->coll->strnncollsp(charset_info, a, a_length,
b, b_length);
return charset_info->coll->strnncoll(charset_info, a, a_length,
- b, b_length);
+ b, b_length, part_key);
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index f11bc9c3475..28e833b8421 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1191,7 +1191,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
}
net_flush(&thd->net);
if ((error= table->file->dump(thd,fd)))
- my_error(ER_GET_ERRNO, MYF(0));
+ my_error(ER_GET_ERRNO, MYF(0), error);
err:
close_thread_tables(thd);
diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c
index 33c686677f1..c84c1c1a2bf 100644
--- a/strings/ctype-big5.c
+++ b/strings/ctype-big5.c
@@ -251,11 +251,12 @@ static int my_strnncoll_big5_internal(const uchar **a_res,
static int my_strnncoll_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 b_is_prefix)
{
uint length= min(a_length, b_length);
int res= my_strnncoll_big5_internal(&a, &b, length);
- return res ? res : (int) (a_length - b_length);
+ return res ? res : (int)((b_is_prefix ? length : a_length) - b_length);
}
diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c
index 54fe4476ae6..5c5e56290e0 100644
--- a/strings/ctype-bin.c
+++ b/strings/ctype-bin.c
@@ -91,10 +91,20 @@ static uchar bin_char_array[] =
static int my_strnncoll_binary(CHARSET_INFO * cs __attribute__((unused)),
const uchar *s, uint slen,
- const uchar *t, uint tlen)
+ const uchar *t, uint tlen,
+ my_bool t_is_prefix)
{
- int cmp= memcmp(s,t,min(slen,tlen));
- return cmp ? cmp : (int) (slen - tlen);
+ uint len=min(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+}
+
+
+static int my_strnncollsp_binary(CHARSET_INFO * cs __attribute__((unused)),
+ const uchar *s, uint slen,
+ const uchar *t, uint tlen)
+{
+ return my_strnncoll_binary(cs,s,slen,t,tlen,0);
}
@@ -335,7 +345,7 @@ MY_COLLATION_HANDLER my_collation_8bit_bin_handler =
{
NULL, /* init */
my_strnncoll_binary,
- my_strnncoll_binary,
+ my_strnncollsp_binary,
my_strnxfrm_bin,
my_like_range_simple,
my_wildcmp_bin,
diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c
index 8fde9498ed9..08677d737ec 100644
--- a/strings/ctype-czech.c
+++ b/strings/ctype-czech.c
@@ -242,12 +242,16 @@ while (1) \
static int my_strnncoll_czech(CHARSET_INFO *cs __attribute__((unused)),
const uchar * s1, uint len1,
- const uchar * s2, uint len2)
+ const uchar * s2, uint len2,
+ my_bool s2_is_prefix)
{
int v1, v2;
const uchar * p1, * p2, * store1, * store2;
int pass1 = 0, pass2 = 0;
+ if (s2_is_prefix && len1 > len2)
+ len1=len2;
+
p1 = s1; p2 = s2;
store1 = s1; store2 = s2;
@@ -276,7 +280,7 @@ int my_strnncollsp_czech(CHARSET_INFO * cs,
{
for ( ; slen && s[slen-1] == ' ' ; slen--);
for ( ; tlen && t[tlen-1] == ' ' ; tlen--);
- return my_strnncoll_czech(cs,s,slen,t,tlen);
+ return my_strnncoll_czech(cs,s,slen,t,tlen,0);
}
diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c
index aec23366ea5..2b31adc2f8a 100644
--- a/strings/ctype-gbk.c
+++ b/strings/ctype-gbk.c
@@ -2614,11 +2614,12 @@ int my_strnncoll_gbk_internal(const uchar **a_res, const uchar **b_res,
int my_strnncoll_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 b_is_prefix)
{
uint length= min(a_length, b_length);
int res= my_strnncoll_gbk_internal(&a, &b, length);
- return res ? res : (int) (a_length - b_length);
+ return res ? res : (int) ((b_is_prefix ? length : a_length) - b_length);
}
diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c
index f5e7fd8baa4..dd9ab4399fb 100644
--- a/strings/ctype-latin1.c
+++ b/strings/ctype-latin1.c
@@ -528,7 +528,8 @@ uchar combo2map[]={
static int my_strnncoll_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 b_is_prefix)
{
const uchar *a_end= a + a_length;
const uchar *b_end= b + b_length;
@@ -561,7 +562,7 @@ static int my_strnncoll_latin1_de(CHARSET_INFO *cs __attribute__((unused)),
A simple test of string lengths won't work -- we test to see
which string ran out first
*/
- return ((a < a_end || a_extend) ? 1 :
+ return ((a < a_end || a_extend) ? (b_is_prefix ? 0 : 1) :
(b < b_end || b_extend) ? -1 : 0);
}
diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c
index c143994dbc3..7b0dadcfa19 100644
--- a/strings/ctype-mb.c
+++ b/strings/ctype-mb.c
@@ -322,7 +322,7 @@ uint my_instr_mb(CHARSET_INFO *cs,
int mblen;
if (!cs->coll->strnncoll(cs, (unsigned char*) b, s_length,
- (unsigned char*) s, s_length))
+ (unsigned char*) s, s_length, 0))
{
if (nmatch)
{
@@ -352,10 +352,19 @@ uint my_instr_mb(CHARSET_INFO *cs,
static int my_strnncoll_mb_bin(CHARSET_INFO * cs __attribute__((unused)),
const uchar *s, uint slen,
- const uchar *t, uint tlen)
+ const uchar *t, uint tlen,
+ my_bool t_is_prefix)
{
- int cmp= memcmp(s,t,min(slen,tlen));
- return cmp ? cmp : (int) (slen - tlen);
+ uint len=min(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int) ((t_is_prefix ? len : slen) - tlen);
+}
+
+static int my_strnncollsp_mb_bin(CHARSET_INFO * cs __attribute__((unused)),
+ const uchar *s, uint slen,
+ const uchar *t, uint tlen)
+{
+ return my_strnncoll_mb_bin(cs,s,slen,t,tlen,0);
}
@@ -514,7 +523,7 @@ MY_COLLATION_HANDLER my_collation_mb_bin_handler =
{
NULL, /* init */
my_strnncoll_mb_bin,
- my_strnncoll_mb_bin,
+ my_strnncollsp_mb_bin,
my_strnxfrm_mb_bin,
my_like_range_simple,
my_wildcmp_mb_bin,
diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c
index 0d30ad28a20..8e295b9e13e 100644
--- a/strings/ctype-simple.c
+++ b/strings/ctype-simple.c
@@ -46,16 +46,19 @@ int my_strnxfrm_simple(CHARSET_INFO * cs,
}
int my_strnncoll_simple(CHARSET_INFO * cs, const uchar *s, uint slen,
- const uchar *t, uint tlen)
+ const uchar *t, uint tlen,
+ my_bool t_is_prefix)
{
int len = ( slen > tlen ) ? tlen : slen;
uchar *map= cs->sort_order;
+ if (t_is_prefix && slen > tlen)
+ slen=tlen;
while (len--)
{
if (map[*s++] != map[*t++])
return ((int) map[s[-1]] - (int) map[t[-1]]);
}
- return (int) (slen-tlen);
+ return (int) (slen - tlen);
}
diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c
index 656c903c7a1..54a0df26f09 100644
--- a/strings/ctype-sjis.c
+++ b/strings/ctype-sjis.c
@@ -232,9 +232,12 @@ static int my_strnncoll_sjis_internal(CHARSET_INFO *cs,
static int my_strnncoll_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 b_is_prefix)
{
int res= my_strnncoll_sjis_internal(cs, &a, a_length, &b, b_length);
+ if (b_is_prefix && a_length > b_length)
+ a_length= b_length;
return res ? res : (int) (a_length - b_length);
}
diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c
index a0ba1a266ea..dae778a8328 100644
--- a/strings/ctype-tis620.c
+++ b/strings/ctype-tis620.c
@@ -529,12 +529,16 @@ static uint thai2sortable(uchar *tstr, uint len)
static
int my_strnncoll_tis620(CHARSET_INFO *cs __attribute__((unused)),
const uchar * s1, uint len1,
- const uchar * s2, uint len2)
+ const uchar * s2, uint len2,
+ my_bool s2_is_prefix)
{
uchar buf[80] ;
uchar *tc1, *tc2;
int i;
+ if (s2_is_prefix && len1 > len2)
+ len1= len2;
+
tc1= buf;
if ((len1 + len2 +2) > (int) sizeof(buf))
tc1= (uchar*) malloc(len1+len2);
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c
index 9997e2772e2..82ab3660111 100644
--- a/strings/ctype-uca.c
+++ b/strings/ctype-uca.c
@@ -6802,7 +6802,8 @@ implicit:
static int my_strnncoll_uca(CHARSET_INFO *cs,
const uchar *s, uint slen,
- const uchar *t, uint tlen)
+ const uchar *t, uint tlen,
+ my_bool t_is_prefix)
{
my_uca_scanner sscanner;
my_uca_scanner tscanner;
@@ -6818,7 +6819,7 @@ static int my_strnncoll_uca(CHARSET_INFO *cs,
t_res= my_uca_scanner_next(&tscanner);
} while ( s_res == t_res && s_res >0);
- return ( s_res - t_res );
+ return (t_is_prefix && t_res < 0) ? 0 : (s_res - t_res);
}
diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c
index f05e85a9d88..58df303a79f 100644
--- a/strings/ctype-ucs2.c
+++ b/strings/ctype-ucs2.c
@@ -182,7 +182,8 @@ static void my_casedn_str_ucs2(CHARSET_INFO *cs __attribute__((unused)),
static int my_strnncoll_ucs2(CHARSET_INFO *cs,
const uchar *s, uint slen,
- const uchar *t, uint tlen)
+ const uchar *t, uint tlen,
+ my_bool t_is_prefix)
{
int s_res,t_res;
my_wc_t s_wc,t_wc;
@@ -213,7 +214,14 @@ static int my_strnncoll_ucs2(CHARSET_INFO *cs,
s+=s_res;
t+=t_res;
}
- return ( (se-s) - (te-t) );
+ return t_is_prefix ? t-te : ((se-s) - (te-t));
+}
+
+static int my_strnncollsp_ucs2(CHARSET_INFO *cs,
+ const uchar *s, uint slen,
+ const uchar *t, uint tlen)
+{
+ return my_strnncoll_ucs2(cs,s,slen,t,tlen,0);
}
@@ -1223,8 +1231,9 @@ int my_wildcmp_ucs2_bin(CHARSET_INFO *cs,
static
int my_strnncoll_ucs2_bin(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 t_is_prefix)
{
int s_res,t_res;
my_wc_t s_wc,t_wc;
@@ -1249,7 +1258,14 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *cs,
s+=s_res;
t+=t_res;
}
- return ( (se-s) - (te-t) );
+ return t_is_prefix ? t-te : ((se-s) - (te-t));
+}
+
+static int my_strnncollsp_ucs2_bin(CHARSET_INFO *cs,
+ const uchar *s, uint slen,
+ const uchar *t, uint tlen)
+{
+ return my_strnncoll_ucs2_bin(cs,s,slen,t,tlen,0);
}
@@ -1374,7 +1390,7 @@ static MY_COLLATION_HANDLER my_collation_ucs2_general_ci_handler =
{
NULL, /* init */
my_strnncoll_ucs2,
- my_strnncoll_ucs2,
+ my_strnncollsp_ucs2,
my_strnxfrm_ucs2,
my_like_range_ucs2,
my_wildcmp_ucs2_ci,
@@ -1388,7 +1404,7 @@ static MY_COLLATION_HANDLER my_collation_ucs2_bin_handler =
{
NULL, /* init */
my_strnncoll_ucs2_bin,
- my_strnncoll_ucs2_bin,
+ my_strnncollsp_ucs2_bin,
my_strnxfrm_ucs2_bin,
my_like_range_simple,
my_wildcmp_ucs2_bin,
diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c
index 02918fcd10f..58f684a0f16 100644
--- a/strings/ctype-utf8.c
+++ b/strings/ctype-utf8.c
@@ -1808,7 +1808,8 @@ static void my_casedn_str_utf8(CHARSET_INFO *cs, char * s)
static int my_strnncoll_utf8(CHARSET_INFO *cs,
const uchar *s, uint slen,
- const uchar *t, uint tlen)
+ const uchar *t, uint tlen,
+ my_bool t_is_prefix)
{
int s_res,t_res;
my_wc_t s_wc,t_wc;
@@ -1839,7 +1840,7 @@ static int my_strnncoll_utf8(CHARSET_INFO *cs,
s+=s_res;
t+=t_res;
}
- return ( (se-s) - (te-t) );
+ return t_is_prefix ? t-te : ((se-s) - (te-t));
}
diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c
index a2c5768b16c..83aaa6839e4 100644
--- a/strings/ctype-win1250ch.c
+++ b/strings/ctype-win1250ch.c
@@ -448,20 +448,25 @@ static struct wordvalue doubles[] = {
static int my_strnncoll_win1250ch(CHARSET_INFO *cs __attribute__((unused)),
const uchar * s1, uint len1,
- const uchar * s2, uint len2)
+ const uchar * s2, uint len2,
+ my_bool s2_is_prefix)
{
int v1, v2;
const uchar * p1, * p2;
int pass1 = 0, pass2 = 0;
int diff;
+ if (s2_is_prefix && len1 > len2)
+ len1=len2;
+
p1 = s1; p2 = s2;
- do {
+ do
+ {
NEXT_CMP_VALUE(s1, p1, pass1, v1, (int)len1);
NEXT_CMP_VALUE(s2, p2, pass2, v2, (int)len2);
- diff = v1 - v2;
- if (diff != 0) return diff;
+ if ((diff = v1 - v2))
+ return diff;
} while (v1);
return 0;
}
@@ -478,7 +483,7 @@ int my_strnncollsp_win1250ch(CHARSET_INFO * cs,
{
for ( ; slen && s[slen-1] == ' ' ; slen--);
for ( ; tlen && t[tlen-1] == ' ' ; tlen--);
- return my_strnncoll_win1250ch(cs,s,slen,t,tlen);
+ return my_strnncoll_win1250ch(cs,s,slen,t,tlen,0);
}