Commit aabcc1f6 authored by serg@sergbook.mysql.com's avatar serg@sergbook.mysql.com

Merge

parents c7b6854f 7118d006
...@@ -50440,6 +50440,9 @@ each individual 4.0.x release. ...@@ -50440,6 +50440,9 @@ each individual 4.0.x release.
@itemize @bullet @itemize @bullet
@item @item
Fixed bug in @code{MATCH ... AGAINST( ... IN BOOLEAN MODE)}
used with @code{ORDER BY}.
@item
Added @code{LOCK TABLES} and @code{CREATE TEMPORARY TABLES} privilege on Added @code{LOCK TABLES} and @code{CREATE TEMPORARY TABLES} privilege on
the database level. One must run the @code{ mysql_fix_privilege_tables} the database level. One must run the @code{ mysql_fix_privilege_tables}
script on old installations to activate these. script on old installations to activate these.
...@@ -93,6 +93,7 @@ typedef struct st_ft_info ...@@ -93,6 +93,7 @@ typedef struct st_ft_info
CHARSET_INFO *charset; CHARSET_INFO *charset;
enum { UNINITIALIZED, READY, INDEX_SEARCH, INDEX_DONE /*, SCAN*/ } state; enum { UNINITIALIZED, READY, INDEX_SEARCH, INDEX_DONE /*, SCAN*/ } state;
uint with_scan; uint with_scan;
my_off_t lastpos;
FTB_EXPR *root; FTB_EXPR *root;
QUEUE queue; QUEUE queue;
TREE no_dupes; TREE no_dupes;
...@@ -297,6 +298,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query, ...@@ -297,6 +298,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
default_charset_info : default_charset_info :
info->s->keyinfo[keynr].seg->charset); info->s->keyinfo[keynr].seg->charset);
ftb->with_scan=0; ftb->with_scan=0;
ftb->lastpos=0;
bzero(& ftb->no_dupes, sizeof(TREE)); bzero(& ftb->no_dupes, sizeof(TREE));
init_alloc_root(&ftb->mem_root, 1024, 1024); init_alloc_root(&ftb->mem_root, 1024, 1024);
...@@ -540,6 +542,21 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) ...@@ -540,6 +542,21 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
if (!ftb->queue.elements) if (!ftb->queue.elements)
return 0; return 0;
if (ftb->state != INDEX_SEARCH && docid < ftb->lastpos)
{
FTB_EXPR *x;
uint i;
for (i=0; i < ftb->queue.elements; i++)
{
ftb->list[i]->docid[1]=HA_POS_ERROR;
for (x=ftb->list[i]->up; x; x=x->up)
x->docid[1]=HA_POS_ERROR;
}
}
ftb->lastpos=docid;
if (ftb->keynr==NO_SUCH_KEY) if (ftb->keynr==NO_SUCH_KEY)
_mi_ft_segiterator_dummy_init(record, length, &ftsi); _mi_ft_segiterator_dummy_init(record, length, &ftsi);
else else
...@@ -557,7 +574,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) ...@@ -557,7 +574,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
int a, b, c; int a, b, c;
for (a=0, b=ftb->queue.elements, c=(a+b)/2; b-a>1; c=(a+b)/2) for (a=0, b=ftb->queue.elements, c=(a+b)/2; b-a>1; c=(a+b)/2)
{ {
ftbw=(FTB_WORD *)(ftb->list[c]); ftbw=ftb->list[c];
if (_mi_compare_text(ftb->charset, word.pos, word.len, if (_mi_compare_text(ftb->charset, word.pos, word.len,
(uchar*) ftbw->word+1, ftbw->len-1, (uchar*) ftbw->word+1, ftbw->len-1,
(my_bool) (ftbw->flags&FTB_FLAG_TRUNC)) >0) (my_bool) (ftbw->flags&FTB_FLAG_TRUNC)) >0)
...@@ -567,7 +584,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) ...@@ -567,7 +584,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
} }
for (; c>=0; c--) for (; c>=0; c--)
{ {
ftbw=(FTB_WORD *)(ftb->list[c]); ftbw=ftb->list[c];
if (_mi_compare_text(ftb->charset, word.pos,word.len, if (_mi_compare_text(ftb->charset, word.pos,word.len,
(uchar*) ftbw->word+1,ftbw->len-1, (uchar*) ftbw->word+1,ftbw->len-1,
(my_bool) (ftbw->flags&FTB_FLAG_TRUNC))) (my_bool) (ftbw->flags&FTB_FLAG_TRUNC)))
...@@ -614,3 +631,4 @@ void ft_boolean_reinit_search(FT_INFO *ftb) ...@@ -614,3 +631,4 @@ void ft_boolean_reinit_search(FT_INFO *ftb)
{ {
_ftb_init_index_search(ftb); _ftb_init_index_search(ftb);
} }
...@@ -64,3 +64,18 @@ a rel ...@@ -64,3 +64,18 @@ a rel
4 1 4 1
7 1 7 1
drop table t1; drop table t1;
CREATE TABLE t1 (
a INT AUTO_INCREMENT PRIMARY KEY,
message CHAR(20),
FULLTEXT(message)
);
INSERT INTO t1 (message) VALUES ("testbug"),("testbug foobar");
SELECT a, MATCH (message) AGAINST ('t* f*' IN BOOLEAN MODE) as rel FROM t1;
a rel
1 1
2 2
SELECT a, MATCH (message) AGAINST ('t* f*' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel,a;
a rel
1 1
2 2
drop table t1;
...@@ -30,3 +30,17 @@ SELECT a, MATCH (message) AGAINST ('steve') as rel FROM t1 ORDER BY rel; ...@@ -30,3 +30,17 @@ SELECT a, MATCH (message) AGAINST ('steve') as rel FROM t1 ORDER BY rel;
SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel; SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel;
drop table t1; drop table t1;
#
# reused boolean scan bug
#
CREATE TABLE t1 (
a INT AUTO_INCREMENT PRIMARY KEY,
message CHAR(20),
FULLTEXT(message)
);
INSERT INTO t1 (message) VALUES ("testbug"),("testbug foobar");
SELECT a, MATCH (message) AGAINST ('t* f*' IN BOOLEAN MODE) as rel FROM t1;
SELECT a, MATCH (message) AGAINST ('t* f*' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel,a;
drop table t1;
...@@ -174,10 +174,8 @@ static int queue_fix_cmp(QUEUE *queue, void **a, void **b) ...@@ -174,10 +174,8 @@ static int queue_fix_cmp(QUEUE *queue, void **a, void **b)
} }
/* /*
Fix heap when every element was changed Fix heap when every element was changed,
actually, it can be done in linear time, actually, it can be done better, in linear time, not in n*log(n)
not in n*log(n), but some code (myisam/ft_boolean_search.c)
requires a strict order here, not just a queue property
*/ */
void queue_fix(QUEUE *queue) void queue_fix(QUEUE *queue)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment