#At file:///home/svoj/devel/bzr-mysql/mysql-5.0-bugteam-push/
2737 Sergey Vojtovich 2008-12-09 [merge]
Merge.
modified:
myisam/ft_boolean_search.c
mysql-test/r/fulltext.result
mysql-test/t/fulltext.test
=== modified file 'myisam/ft_boolean_search.c'
--- a/myisam/ft_boolean_search.c 2008-01-23 15:03:58 +0000
+++ b/myisam/ft_boolean_search.c 2008-11-28 14:17:13 +0000
@@ -122,11 +122,11 @@ static int FTB_WORD_cmp(my_off_t *v, FTB
static int FTB_WORD_cmp_list(CHARSET_INFO *cs, FTB_WORD **a, FTB_WORD **b)
{
- /* ORDER BY word DESC, ndepth DESC */
- int i= mi_compare_text(cs, (uchar*) (*b)->word+1,(*b)->len-1,
- (uchar*) (*a)->word+1,(*a)->len-1,0,0);
+ /* ORDER BY word, ndepth */
+ int i= mi_compare_text(cs, (uchar*) (*a)->word + 1, (*a)->len - 1,
+ (uchar*) (*b)->word + 1, (*b)->len - 1, 0, 0);
if (!i)
- i=CMP_NUM((*b)->ndepth,(*a)->ndepth);
+ i= CMP_NUM((*a)->ndepth, (*b)->ndepth);
return i;
}
@@ -674,23 +674,49 @@ float ft_boolean_find_relevance(FT_INFO
(byte *) end, &word, TRUE))
{
int a, b, c;
+ /*
+ Find right-most element in the array of query words matching this
+ word from a document.
+ */
for (a=0, b=ftb->queue.elements, c=(a+b)/2; b-a>1; c=(a+b)/2)
{
ftbw=ftb->list[c];
if (mi_compare_text(ftb->charset, (uchar*) word.pos, word.len,
(uchar*) ftbw->word+1, ftbw->len-1,
- (my_bool) (ftbw->flags&FTB_FLAG_TRUNC),0) >0)
+ (my_bool) (ftbw->flags & FTB_FLAG_TRUNC), 0) < 0)
b=c;
else
a=c;
}
+ /*
+ If there were no words with truncation operator, we iterate to the
+ beginning of an array until array element is equal to the word from
+ a document. This is done mainly because the same word may be
+ mentioned twice (or more) in the query.
+
+ In case query has words with truncation operator we must iterate
+ to the beginning of the array. There may be non-matching query words
+ between matching word with truncation operator and the right-most
+ matching element. E.g., if we're looking for 'aaa15' in an array of
+ 'aaa1* aaa14 aaa15 aaa16'.
+
+ Worse of that there still may be match even if the binary search
+ above didn't find matching element. E.g., if we're looking for
+ 'aaa15' in an array of 'aaa1* aaa14 aaa16'. The binary search will
+ stop at 'aaa16'.
+ */
for (; c>=0; c--)
{
ftbw=ftb->list[c];
if (mi_compare_text(ftb->charset, (uchar*) word.pos, word.len,
(uchar*) ftbw->word+1,ftbw->len-1,
(my_bool) (ftbw->flags&FTB_FLAG_TRUNC),0))
- break;
+ {
+ if (ftb->with_scan & FTB_FLAG_TRUNC)
+ continue;
+ else
+ break;
+ }
if (ftbw->docid[1] == docid)
continue;
ftbw->docid[1]=docid;
=== modified file 'mysql-test/r/fulltext.result'
--- a/mysql-test/r/fulltext.result 2008-11-11 09:10:51 +0000
+++ b/mysql-test/r/fulltext.result 2008-11-28 14:17:13 +0000
@@ -497,3 +497,12 @@ WHERE MATCH(a) AGAINST('test' IN BOOLEAN
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref b b 5 const 4 Using where
DROP TABLE t1;
+CREATE TABLE t1(a CHAR(10));
+INSERT INTO t1 VALUES('aaa15');
+SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa16' IN BOOLEAN MODE) FROM t1;
+MATCH(a) AGAINST('aaa1* aaa14 aaa16' IN BOOLEAN MODE)
+1
+SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) FROM t1;
+MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE)
+2
+DROP TABLE t1;
=== modified file 'mysql-test/t/fulltext.test'
--- a/mysql-test/t/fulltext.test 2008-11-11 09:10:51 +0000
+++ b/mysql-test/t/fulltext.test 2008-11-28 14:17:13 +0000
@@ -423,3 +423,12 @@ EXPLAIN SELECT * FROM t1 FORCE INDEX(b)
WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1;
DROP TABLE t1;
+
+#
+# BUG#37245 - Full text search problem
+#
+CREATE TABLE t1(a CHAR(10));
+INSERT INTO t1 VALUES('aaa15');
+SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa16' IN BOOLEAN MODE) FROM t1;
+SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) FROM t1;
+DROP TABLE t1;
| Thread |
|---|
| • bzr commit into mysql-5.0-bugteam branch (svoj:2737) | Sergey Vojtovich | 9 Dec |