diff options
author | serg@janus.mylan <> | 2007-07-11 15:26:19 +0200 |
---|---|---|
committer | serg@janus.mylan <> | 2007-07-11 15:26:19 +0200 |
commit | 859304f70828475730745c2bcbfb90a1a6224456 (patch) | |
tree | 92e51308f72b9775069ff6712b8b4db0a19c3b0e | |
parent | 05a12b7bb7b0bd382edf08bfbe4b6e07e4d69d03 (diff) | |
download | mariadb-git-859304f70828475730745c2bcbfb90a1a6224456.tar.gz |
fix for smarter index mergein fulltext
to work for queries like "+a (b)"
-rw-r--r-- | mysql-test/r/fulltext.result | 3 | ||||
-rw-r--r-- | mysql-test/t/fulltext.test | 1 | ||||
-rw-r--r-- | storage/myisam/ft_boolean_search.c | 25 |
3 files changed, 23 insertions, 6 deletions
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 6f6760e31bc..02b115cb6dc 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -485,4 +485,7 @@ INSERT INTO t1 VALUES('Offside'),('City Of God'); SELECT a FROM t1 WHERE MATCH a AGAINST ('+city of*' IN BOOLEAN MODE); a City Of God +SELECT a FROM t1 WHERE MATCH a AGAINST ('+city (of)*' IN BOOLEAN MODE); +a +City Of God DROP TABLE t1; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 4e0c65267c4..b1bf0036c70 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -414,6 +414,7 @@ DROP TABLE t1; CREATE TABLE t1(a VARCHAR(20), FULLTEXT(a)); INSERT INTO t1 VALUES('Offside'),('City Of God'); SELECT a FROM t1 WHERE MATCH a AGAINST ('+city of*' IN BOOLEAN MODE); +SELECT a FROM t1 WHERE MATCH a AGAINST ('+city (of)*' IN BOOLEAN MODE); DROP TABLE t1; # End of 4.1 tests diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c index ce93ba28da9..5c421d3688b 100644 --- a/storage/myisam/ft_boolean_search.c +++ b/storage/myisam/ft_boolean_search.c @@ -24,7 +24,7 @@ subtree, but it could be updated by plus-word only. The idea is: there is no need to search for docid smaller than - biggest docid inside current plus subtree. + biggest docid inside current plus subtree or any upper plus subtree. Examples: +word1 word2 @@ -36,6 +36,13 @@ +(word1 -word2) +(+word3 word4) share same max_docid max_docid updated by word3 + +word1 word2 (+word3 word4 (+word5 word6)) + three subexpressions (including the top-level one), + every one has its own max_docid, updated by its plus word. + but for the search word6 uses + max(word1.max_docid, word3.max_docid, word5.max_docid), + while word4 uses, accordingly, + max(word1.max_docid, word3.max_docid). */ #define FT_CORE @@ -104,7 +111,7 @@ typedef struct st_ftb_word /* ^^^^^^^^^^^^^^^^^^ FTB_{EXPR,WORD} common section */ my_off_t docid[2]; /* for index search and for scan */ my_off_t key_root; - my_off_t *max_docid; + FTB_EXPR *max_docid_expr; MI_KEYDEF *keyinfo; struct st_ftb_word *prev; float weight; @@ -208,7 +215,7 @@ static int ftb_query_add_word(MYSQL_FTPARSER_PARAM *param, for (tmp_expr= ftb_param->ftbe; tmp_expr->up; tmp_expr= tmp_expr->up) if (! (tmp_expr->flags & FTB_FLAG_YES)) break; - ftbw->max_docid= &tmp_expr->max_docid; + ftbw->max_docid_expr= tmp_expr; /* fall through */ case FT_TOKEN_STOPWORD: if (! ftb_param->up_quot) break; @@ -347,11 +354,17 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) else { uint sflag= SEARCH_BIGGER; - if (ftbw->docid[0] < *ftbw->max_docid) + my_off_t max_docid=0; + FTB_EXPR *tmp; + + for (tmp= ftbw->max_docid_expr; tmp; tmp= tmp->up) + set_if_bigger(max_docid, tmp->max_docid); + + if (ftbw->docid[0] < max_docid) { sflag|= SEARCH_SAME; _mi_dpointer(info, (uchar *)(ftbw->word + ftbw->len + HA_FT_WLEN), - *ftbw->max_docid); + max_docid); } r=_mi_search(info, ftbw->keyinfo, (uchar*) lastkey_buf, USE_WHOLE_KEY, sflag, ftbw->key_root); @@ -431,7 +444,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) } ftbw->docid[0]=info->lastpos; if (ftbw->flags & FTB_FLAG_YES) - *ftbw->max_docid= info->lastpos; + ftbw->max_docid_expr->max_docid= info->lastpos; return 0; } |