diff options
-rw-r--r-- | myisam/ft_boolean_search.c | 51 | ||||
-rw-r--r-- | mysql-test/r/fulltext.result | 17 | ||||
-rw-r--r-- | mysql-test/r/fulltext_left_join.result | 8 | ||||
-rw-r--r-- | mysql-test/t/fulltext.test | 11 | ||||
-rw-r--r-- | mysql-test/t/fulltext_left_join.test | 2 |
5 files changed, 70 insertions, 19 deletions
diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c index e44516c16d6..aa41bc11513 100644 --- a/myisam/ft_boolean_search.c +++ b/myisam/ft_boolean_search.c @@ -61,10 +61,11 @@ typedef struct st_ftb_expr FTB_EXPR; struct st_ftb_expr { FTB_EXPR *up; - byte *quot, *qend; - my_off_t docid[2]; /* for index search and for scan */ + my_off_t docid[2]; +/* ^^^^^^^^^^^^^^^^^^ FTB_{EXPR,WORD} common section */ float weight; float cur_weight; + byte *quot, *qend; uint flags; uint yesses; /* number of "yes" words matched */ uint nos; /* number of "no" words matched */ @@ -77,6 +78,7 @@ typedef struct st_ftb_word FTB_EXPR *up; MI_KEYDEF *keyinfo; my_off_t docid[2]; /* for index search and for scan */ +/* ^^^^^^^^^^^^^^^^^^ FTB_{EXPR,WORD} common section */ my_off_t key_root; float weight; uint ndepth; @@ -299,13 +301,15 @@ static void _ftb_init_index_search(FT_INFO *ftb) if (ftbw->flags & FTB_FLAG_TRUNC) { /* - special treatment for truncation operator :(( - 1. +trunc* and there're other (not +trunc*) words + special treatment for truncation operator + 1. there are some (besides this) +words | no need to search in the index, it can never ADD new rows | to the result, and to remove half-matched rows we do scan anyway 2. -trunc* | same as 1. - 3. trunc* + 3. in 1 and 2, +/- need not be on the same expr. level, + but can be on any upper level, as in +word +(trunc1* trunc2*) + 4. otherwise | We have to index-search for this prefix. | It may cause duplicates, as in the index (sorted by <word,docid>) | <aaaa,row1> @@ -313,22 +317,31 @@ static void _ftb_init_index_search(FT_INFO *ftb) | <aacc,row1> | Searching for "aa*" will find row1 twice... */ - if ( test(ftbw->flags&FTB_FLAG_NO) || /* 2 */ - (test(ftbw->flags&FTB_FLAG_YES) && /* 1 */ - ftbw->up->ythresh - ftbw->up->yweaks >1)) /* 1 */ - { - ftbw->docid[0]=HA_POS_ERROR; - ftbw->up->yweaks++; - continue; - } - else /* 3 */ + FTB_EXPR *ftbe; + for (ftbe=(FTB_EXPR*)ftbw; + ftbe->up && !(ftbe->up->flags & FTB_FLAG_TRUNC); + ftbe->up->flags|= FTB_FLAG_TRUNC, ftbe=ftbe->up) { - if (!is_tree_inited(& ftb->no_dupes)) - init_tree(&ftb->no_dupes,0,0,sizeof(my_off_t), - _ftb_no_dupes_cmp, 0, NULL, NULL); - else - reset_tree(& ftb->no_dupes); + if (ftbe->flags & FTB_FLAG_NO || /* 2 */ + ftbe->up->ythresh - ftbe->up->yweaks >1) /* 1 */ + { + FTB_EXPR *top_ftbe=ftbe->up->up; + ftbw->docid[0]=HA_POS_ERROR; + for (ftbe=ftbw->up; ftbe != top_ftbe; ftbe=ftbe->up) + if (ftbe->flags & FTB_FLAG_YES) + ftbe->yweaks++; + ftbe=0; + break; + } } + if (!ftbe) + continue; + /* 3 */ + if (!is_tree_inited(& ftb->no_dupes)) + init_tree(& ftb->no_dupes,0,0,sizeof(my_off_t), + _ftb_no_dupes_cmp,0,0,0); + else + reset_tree(& ftb->no_dupes); } if (_ft2_search(ftb, ftbw, 1)) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 5cb4263f649..191331e7a2a 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -161,6 +161,23 @@ Only MyISAM tables support collections Function MATCH ... AGAINST() is used to do a search some test foobar implements vector space model drop table t1; +create table t1 (a varchar(200) not null, fulltext (a)); +insert t1 values ("aaa10 bbb20"), ("aaa20 bbb15"), ("aaa30 bbb10"); +select * from t1 where match a against ("+aaa* +bbb*" in boolean mode); +a +aaa10 bbb20 +aaa20 bbb15 +aaa30 bbb10 +select * from t1 where match a against ("+aaa* +bbb1*" in boolean mode); +a +aaa20 bbb15 +aaa30 bbb10 +select * from t1 where match a against ("+aaa* +ccc*" in boolean mode); +a +select * from t1 where match a against ("+aaa10 +(bbb*)" in boolean mode); +a +aaa10 bbb20 +drop table t1; CREATE TABLE t1 ( id int(11), ticket int(11), diff --git a/mysql-test/r/fulltext_left_join.result b/mysql-test/r/fulltext_left_join.result index 6875a517718..d215ea0cea8 100644 --- a/mysql-test/r/fulltext_left_join.result +++ b/mysql-test/r/fulltext_left_join.result @@ -41,4 +41,12 @@ venue_id venue_text dt name entity_id select * from t1 left join t2 on venue_id = entity_id where match(name) against('aberdeen') and dt = '2003-05-23 19:30:00'; venue_id venue_text dt name entity_id 1 a1 2003-05-23 19:30:00 aberdeen town hall 1 +select * from t1 left join t2 on (venue_id = entity_id and match(name) against('aberdeen' in boolean mode)) where dt = '2003-05-23 19:30:00'; +venue_id venue_text dt name entity_id +1 a1 2003-05-23 19:30:00 aberdeen town hall 1 +NULL a2 2003-05-23 19:30:00 NULL NULL +select * from t1 left join t2 on (venue_id = entity_id and match(name) against('aberdeen')) where dt = '2003-05-23 19:30:00'; +venue_id venue_text dt name entity_id +1 a1 2003-05-23 19:30:00 aberdeen town hall 1 +NULL a2 2003-05-23 19:30:00 NULL NULL drop table t1,t2; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index a0292740c8d..38c09682bac 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -81,6 +81,17 @@ select * from t1; drop table t1; # +# why to scan strings for trunc* +# +create table t1 (a varchar(200) not null, fulltext (a)); +insert t1 values ("aaa10 bbb20"), ("aaa20 bbb15"), ("aaa30 bbb10"); +select * from t1 where match a against ("+aaa* +bbb*" in boolean mode); +select * from t1 where match a against ("+aaa* +bbb1*" in boolean mode); +select * from t1 where match a against ("+aaa* +ccc*" in boolean mode); +select * from t1 where match a against ("+aaa10 +(bbb*)" in boolean mode); +drop table t1; + +# # Check bug reported by Matthias Urlichs # diff --git a/mysql-test/t/fulltext_left_join.test b/mysql-test/t/fulltext_left_join.test index 855649923c4..e3083ddc4e1 100644 --- a/mysql-test/t/fulltext_left_join.test +++ b/mysql-test/t/fulltext_left_join.test @@ -41,5 +41,7 @@ create table t2 (name varchar(255) not null default '', entity_id int(11) not nu insert into t2 (name, entity_id) values ('aberdeen town hall', 1), ('glasgow royal concert hall', 2), ('queen\'s hall, edinburgh', 3); select * from t1 left join t2 on venue_id = entity_id where match(name) against('aberdeen' in boolean mode) and dt = '2003-05-23 19:30:00'; select * from t1 left join t2 on venue_id = entity_id where match(name) against('aberdeen') and dt = '2003-05-23 19:30:00'; +select * from t1 left join t2 on (venue_id = entity_id and match(name) against('aberdeen' in boolean mode)) where dt = '2003-05-23 19:30:00'; +select * from t1 left join t2 on (venue_id = entity_id and match(name) against('aberdeen')) where dt = '2003-05-23 19:30:00'; drop table t1,t2; |