Commit 5adb4dd2 authored by unknown's avatar unknown

Many MATCH'es per query now allowed (i.e. AND's and OR's now work, but

slow - full table scan); ORDER BY now works with MATCH (slow, full table
scan)


myisam/ft_eval.c:
  ft_read_next compatibility
myisam/ft_test1.c:
  ft_read_next compatibility
include/ft_global.h:
  ft_read_next redesigned, ft_get_relevance introduced
sql/ha_myisam.cc:
  Many MATCH'es per query now allowed
sql/ha_myisam.h:
  Many MATCH'es per query now allowed
sql/handler.h:
  Many MATCH'es per query now allowed
sql/item_func.cc:
  Many MATCH'es per query now allowed
sql/item_func.h:
  Many MATCH'es per query now allowed
sql/sql_select.cc:
  Many MATCH'es per query now allowed
myisam/ft_search.c:
  HA_KEY_NOT_FOUND => HA_END_OF_FILE
parent 7fb9a554
...@@ -43,8 +43,9 @@ typedef struct st_ft_doclist { ...@@ -43,8 +43,9 @@ typedef struct st_ft_doclist {
int ft_init_stopwords(const char **); int ft_init_stopwords(const char **);
FT_DOCLIST * ft_init_search(void *, uint, byte *, uint, my_bool); FT_DOCLIST * ft_init_search(void *, uint, byte *, uint, my_bool);
double ft_read_next(FT_DOCLIST *, char *); int ft_read_next(FT_DOCLIST *, char *);
#define ft_close_search(handler) my_free(((gptr)(handler)),MYF(0)) #define ft_close_search(handler) my_free(((gptr)(handler)),MYF(0))
#define ft_get_relevance(handler) ((handler)->doc[(handler)->curdoc].weight)
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -82,7 +82,7 @@ int main(int argc,char *argv[]) ...@@ -82,7 +82,7 @@ int main(int argc,char *argv[])
if (!silent) if (!silent)
printf("- Reading rows with key\n"); printf("- Reading rows with key\n");
for(i=1;create_record(record,qf);i++) { for(i=1;create_record(record,qf);i++) {
FT_DOCLIST *result; double w; int t; FT_DOCLIST *result; double w; int t,err;
result=ft_init_search(file,0,blob_record,(uint) strlen(blob_record),1); result=ft_init_search(file,0,blob_record,(uint) strlen(blob_record),1);
if(!result) { if(!result) {
...@@ -91,11 +91,12 @@ int main(int argc,char *argv[]) ...@@ -91,11 +91,12 @@ int main(int argc,char *argv[])
} }
if (!silent) if (!silent)
printf("Query %d. Found: %d.\n",i,result->ndocs); printf("Query %d. Found: %d.\n",i,result->ndocs);
for(j=0;(w=ft_read_next(result, read_record))>0;j++) { for(j=0;(err=ft_read_next(result, read_record))==0;j++) {
t=uint2korr(read_record); t=uint2korr(read_record);
w=ft_get_relevance(result);
printf("%d %.*s %f\n",i,t,read_record+2,w); printf("%d %.*s %f\n",i,t,read_record+2,w);
} }
if(w<0) { if(err != HA_ERR_KEY_NOT_FOUND) {
printf("ft_read_next %d failed with errno %3d\n",j,my_errno); printf("ft_read_next %d failed with errno %3d\n",j,my_errno);
goto err; goto err;
} }
......
...@@ -187,7 +187,7 @@ FT_DOCLIST * ft_init_search(void *info, uint keynr, byte *key, ...@@ -187,7 +187,7 @@ FT_DOCLIST * ft_init_search(void *info, uint keynr, byte *key,
goto err; goto err;
dlist->ndocs=aio.dtree.elements_in_tree; dlist->ndocs=aio.dtree.elements_in_tree;
dlist->curdoc=0; dlist->curdoc=-1;
dlist->info=aio.info; dlist->info=aio.info;
dptr=dlist->doc; dptr=dlist->doc;
...@@ -205,19 +205,19 @@ FT_DOCLIST * ft_init_search(void *info, uint keynr, byte *key, ...@@ -205,19 +205,19 @@ FT_DOCLIST * ft_init_search(void *info, uint keynr, byte *key,
return dlist; return dlist;
} }
double ft_read_next(FT_DOCLIST *handler, char *record) int ft_read_next(FT_DOCLIST *handler, char *record)
{ {
MI_INFO *info=handler->info; MI_INFO *info=handler->info;
if (handler->curdoc >= handler->ndocs) if (++handler->curdoc >= handler->ndocs)
return 0; return HA_ERR_END_OF_FILE;
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
if (!(*info->read_record)(info,handler->doc[handler->curdoc].dpos,record)) if (!(*info->read_record)(info,handler->doc[handler->curdoc].dpos,record))
{ {
info->update|= HA_STATE_AKTIV; /* Record is read */ info->update|= HA_STATE_AKTIV; /* Record is read */
return handler->doc[handler->curdoc++].weight; return 0;
} }
return -my_errno; return my_errno;
} }
...@@ -145,15 +145,16 @@ static int run_test(const char *filename) ...@@ -145,15 +145,16 @@ static int run_test(const char *filename)
} }
printf("Query %d: `%s'. Found: %d. Top five documents:\n", printf("Query %d: `%s'. Found: %d. Top five documents:\n",
i,query[i],result->ndocs); i,query[i],result->ndocs);
for(j=0;j<5;j++) { double w; for(j=0;j<5;j++) { double w; int err;
w=ft_read_next(result, read_record); err=ft_read_next(result, read_record);
if(w<0) { if(err==HA_ERR_KEY_NOT_FOUND) {
printf("ft_read_next %d failed with errno %3d\n",j,my_errno);
break;
} else if (w==0) {
printf("No more matches!\n"); printf("No more matches!\n");
break; break;
} else if (err) {
printf("ft_read_next %d failed with errno %3d\n",j,my_errno);
break;
} }
w=ft_get_relevance(result);
if(key_field == FIELD_VARCHAR) { if(key_field == FIELD_VARCHAR) {
uint l; uint l;
char *p; char *p;
......
...@@ -904,15 +904,13 @@ int ha_myisam::ft_read(byte * buf) ...@@ -904,15 +904,13 @@ int ha_myisam::ft_read(byte * buf)
{ {
int error; int error;
if (!ft_handler)
return -1;
thread_safe_increment(ha_read_next_count,&LOCK_status); // why ? thread_safe_increment(ha_read_next_count,&LOCK_status); // why ?
if (ft_handler)
ft_relevance=ft_read_next((FT_DOCLIST *) ft_handler,(char*) buf);
else
ft_relevance=0;
error=((ft_relevance == 0) ? HA_ERR_END_OF_FILE : error=ft_read_next((FT_DOCLIST *) ft_handler,(char*) buf);
(ft_relevance > 0) ? 0 :
(int) -ft_relevance);
table->status=error ? STATUS_NOT_FOUND: 0; table->status=error ? STATUS_NOT_FOUND: 0;
return error; return error;
} }
...@@ -40,7 +40,7 @@ class ha_myisam: public handler ...@@ -40,7 +40,7 @@ class ha_myisam: public handler
HA_LONGLONG_KEYS+ HA_NULL_KEY + HA_LONGLONG_KEYS+ HA_NULL_KEY +
HA_DUPP_POS + HA_BLOB_KEY + HA_AUTO_PART_KEY) HA_DUPP_POS + HA_BLOB_KEY + HA_AUTO_PART_KEY)
{} {}
~ha_myisam() { ft_close(); } ~ha_myisam() {}
const char *table_type() const { return "MyISAM"; } const char *table_type() const { return "MyISAM"; }
const char **bas_ext() const; const char **bas_ext() const;
ulong option_flag() const { return int_option_flag; } ulong option_flag() const { return int_option_flag; }
...@@ -63,9 +63,10 @@ class ha_myisam: public handler ...@@ -63,9 +63,10 @@ class ha_myisam: public handler
int index_first(byte * buf); int index_first(byte * buf);
int index_last(byte * buf); int index_last(byte * buf);
int index_next_same(byte *buf, const byte *key, uint keylen); int index_next_same(byte *buf, const byte *key, uint keylen);
int ft_init(uint inx,const byte *key, uint keylen, bool presort); int ft_init(uint inx,const byte *key, uint keylen, bool presort=1);
void *ft_init_ext(uint inx,const byte *key, uint keylen, bool presort=0)
{ return ft_init_search(file,inx,(byte*) key,keylen,presort); }
int ft_read(byte *buf); int ft_read(byte *buf);
int ft_close() { if(ft_handler) ft_close_search(ft_handler); ft_handler=0; return 0;}
int rnd_init(bool scan=1); int rnd_init(bool scan=1);
int rnd_next(byte *buf); int rnd_next(byte *buf);
int rnd_pos(byte * buf, byte *pos); int rnd_pos(byte * buf, byte *pos);
......
...@@ -189,7 +189,6 @@ class handler :public Sql_alloc ...@@ -189,7 +189,6 @@ class handler :public Sql_alloc
time_t check_time; time_t check_time;
time_t update_time; time_t update_time;
ulong mean_rec_length; /* physical reclength */ ulong mean_rec_length; /* physical reclength */
double ft_relevance;
void *ft_handler; void *ft_handler;
handler(TABLE *table_arg) : table(table_arg),active_index(MAX_REF_PARTS), handler(TABLE *table_arg) : table(table_arg),active_index(MAX_REF_PARTS),
...@@ -198,7 +197,7 @@ class handler :public Sql_alloc ...@@ -198,7 +197,7 @@ class handler :public Sql_alloc
delete_length(0), auto_increment_value(0), raid_type(0), delete_length(0), auto_increment_value(0), raid_type(0),
key_used_on_scan(MAX_KEY), key_used_on_scan(MAX_KEY),
create_time(0), check_time(0), update_time(0), mean_rec_length(0), create_time(0), check_time(0), update_time(0), mean_rec_length(0),
ft_relevance(0.0), ft_handler(0) ft_handler(0)
{} {}
virtual ~handler(void) { my_free((char*) ref,MYF(MY_ALLOW_ZERO_PTR)); } virtual ~handler(void) { my_free((char*) ref,MYF(MY_ALLOW_ZERO_PTR)); }
int ha_open(const char *name, int mode, int test_if_locked); int ha_open(const char *name, int mode, int test_if_locked);
...@@ -231,10 +230,11 @@ class handler :public Sql_alloc ...@@ -231,10 +230,11 @@ class handler :public Sql_alloc
virtual int index_first(byte * buf)=0; virtual int index_first(byte * buf)=0;
virtual int index_last(byte * buf)=0; virtual int index_last(byte * buf)=0;
virtual int index_next_same(byte *buf, const byte *key, uint keylen); virtual int index_next_same(byte *buf, const byte *key, uint keylen);
virtual int ft_init(uint inx,const byte *key, uint keylen, bool presort) virtual int ft_init(uint inx,const byte *key, uint keylen, bool presort=1)
{ return -1; } { return -1; }
virtual void *ft_init_ext(uint inx,const byte *key, uint keylen, bool presort=0)
{ return (void *)NULL; }
virtual int ft_read(byte *buf) { return -1; } virtual int ft_read(byte *buf) { return -1; }
virtual int ft_close() { return -1; }
virtual int rnd_init(bool scan=1)=0; virtual int rnd_init(bool scan=1)=0;
virtual int rnd_end() { return 0; } virtual int rnd_end() { return 0; }
virtual int rnd_next(byte *buf)=0; virtual int rnd_next(byte *buf)=0;
......
...@@ -1837,13 +1837,14 @@ longlong Item_func_inet_aton::val_int() ...@@ -1837,13 +1837,14 @@ longlong Item_func_inet_aton::val_int()
double Item_func_match::val() double Item_func_match::val()
{ {
int a,b,c; my_off_t docid=table->file->row_position(); // HAVE to do it here...
FT_DOC *docs;
my_off_t docid;
docid = table->file->row_position(); // HAVE to do it here...
if (table->file->ft_handler==NULL && !auto_init_was_done) if (first_call)
{
if (join_key=(table->file->get_index() == key &&
(ft_handler=(FT_DOCLIST *)table->file->ft_handler)))
;
else
{ {
/* join won't use this ft-key, but we must to init it anyway */ /* join won't use this ft-key, but we must to init it anyway */
String *ft_tmp=0; String *ft_tmp=0;
...@@ -1851,29 +1852,34 @@ double Item_func_match::val() ...@@ -1851,29 +1852,34 @@ double Item_func_match::val()
String tmp2(tmp1,sizeof(tmp1)); String tmp2(tmp1,sizeof(tmp1));
ft_tmp=key_item()->val_str(&tmp2); ft_tmp=key_item()->val_str(&tmp2);
table->file->ft_init(key, (byte*) ft_tmp->ptr(), ft_tmp->length(), FALSE); ft_handler=(FT_DOCLIST *)
auto_init_was_done=1; table->file->ft_init_ext(key, (byte*) ft_tmp->ptr(), ft_tmp->length());
}
first_call=0;
} }
// Don't know how to return an error from val(), so NULL will be returned // Don't know how to return an error from val(), so NULL will be returned
if ((null_value=(table->file->ft_handler==NULL))) if ((null_value=(ft_handler==NULL)))
return 0.0; return 0.0;
if (auto_init_was_done) if (join_key)
{
return ft_get_relevance(ft_handler);
}
else
{ {
/* implicit initialization was done, so nobody will set proper /* implicit initialization was done, so we'll have to find
ft_relevance for us. We'll look for it in ft_handler array */ ft_relevance manually in ft_handler array */
docs = ((FT_DOCLIST *)table->file->ft_handler)->doc; int a,b,c;
// docid = table->file->row_position(); FT_DOC *docs=ft_handler->doc;
if ((null_value=(docid==HA_OFFSET_ERROR))) if ((null_value=(docid==HA_OFFSET_ERROR)))
return 0.0; return 0.0;
// Assuming docs[] is sorted by dpos... // Assuming docs[] is sorted by dpos...
a=0, b=((FT_DOCLIST *)table->file->ft_handler)->ndocs; for (a=0, b=ft_handler->ndocs, c=(a+b)/2; b-a>1; c=(a+b)/2)
for (c=(a+b)/2; b-a>1; c=(a+b)/2)
{ {
if (docs[c].dpos > docid) if (docs[c].dpos > docid)
b=c; b=c;
...@@ -1881,12 +1887,10 @@ double Item_func_match::val() ...@@ -1881,12 +1887,10 @@ double Item_func_match::val()
a=c; a=c;
} }
if (docs[a].dpos == docid) if (docs[a].dpos == docid)
table->file->ft_relevance=docs[a].weight; return docs[a].weight;
else else
table->file->ft_relevance=0; return 0.0;
} }
return table->file->ft_relevance;
} }
bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist) bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
...@@ -1912,8 +1916,6 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist) ...@@ -1912,8 +1916,6 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
return 1; return 1;
const_item_cache=0; const_item_cache=0;
table=((Item_field *)fields.head())->field->table; table=((Item_field *)fields.head())->field->table;
auto_init_was_done=0;
table->file->ft_close(); // It's a bad solution to do it here, I know :-(
return 0; return 0;
} }
...@@ -1978,7 +1980,7 @@ bool Item_func_match::fix_index() ...@@ -1978,7 +1980,7 @@ bool Item_func_match::fix_index()
} }
this->key=max_key; this->key=max_key;
first_call=1;
maybe_null=1; maybe_null=1;
return 0; return 0;
......
...@@ -830,22 +830,23 @@ class Item_func_inet_aton : public Item_int_func ...@@ -830,22 +830,23 @@ class Item_func_inet_aton : public Item_int_func
/* SerG: for fulltext search */ /* SerG: for fulltext search */
#include <ft_global.h>
class Item_func_match :public Item_real_func class Item_func_match :public Item_real_func
{ {
public: public:
// handler *File;
List<Item> fields; List<Item> fields;
TABLE *table; TABLE *table;
uint key; uint key;
bool auto_init_was_done; bool first_call, join_key;
FT_DOCLIST *ft_handler;
Item_func_match(List<Item> &a, Item *b): Item_real_func(b), Item_func_match(List<Item> &a, Item *b): Item_real_func(b),
fields(a), table(0) fields(a), table(0), ft_handler(0)
{} {}
~Item_func_match() {} ~Item_func_match() { ft_close_search(ft_handler);
if(join_key) table->file->ft_handler=0; }
const char *func_name() const { return "match"; } const char *func_name() const { return "match"; }
//optimize_type select_optimize() const { return OPTIMIZE_FT; }
enum Functype functype() const { return FT_FUNC; } enum Functype functype() const { return FT_FUNC; }
void update_used_tables() {} void update_used_tables() {}
bool fix_fields(THD *thd,struct st_table_list *tlist); bool fix_fields(THD *thd,struct st_table_list *tlist);
......
...@@ -476,6 +476,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -476,6 +476,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
as in other cases the join is done before the sort. as in other cases the join is done before the sort.
*/ */
if ((order || group) && join.join_tab[join.const_tables].type != JT_ALL && if ((order || group) && join.join_tab[join.const_tables].type != JT_ALL &&
join.join_tab[join.const_tables].type != JT_FT && /* Beware! SerG */
(order && simple_order || group && simple_group)) (order && simple_order || group && simple_group))
{ {
if (add_ref_to_table_cond(thd,&join.join_tab[join.const_tables])) if (add_ref_to_table_cond(thd,&join.join_tab[join.const_tables]))
...@@ -4281,7 +4282,7 @@ join_ft_read_first(JOIN_TAB *tab) ...@@ -4281,7 +4282,7 @@ join_ft_read_first(JOIN_TAB *tab)
#endif #endif
if ((error=table->file->ft_init(tab->ref.key, if ((error=table->file->ft_init(tab->ref.key,
tab->ref.key_buff, tab->ref.key_buff,
tab->ref.key_length,TRUE))) tab->ref.key_length)))
{ {
if (error != HA_ERR_KEY_NOT_FOUND) if (error != HA_ERR_KEY_NOT_FOUND)
{ {
...@@ -4303,7 +4304,6 @@ join_ft_read_first(JOIN_TAB *tab) ...@@ -4303,7 +4304,6 @@ join_ft_read_first(JOIN_TAB *tab)
table->file->print_error(error,MYF(0)); table->file->print_error(error,MYF(0));
return 1; return 1;
} }
table->file->ft_close();
return -1; return -1;
} }
return 0; return 0;
...@@ -4322,7 +4322,6 @@ join_ft_read_next(READ_RECORD *info) ...@@ -4322,7 +4322,6 @@ join_ft_read_next(READ_RECORD *info)
info->file->print_error(error,MYF(0)); info->file->print_error(error,MYF(0));
return 1; return 1;
} }
info->file->ft_close();
return -1; return -1;
} }
return 0; return 0;
...@@ -4974,6 +4973,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) ...@@ -4974,6 +4973,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
} }
} }
else else
if (tab->type != JT_FT) /* Beware! SerG */
{ {
/* /*
We have a ref on a const; Change this to a range that filesort We have a ref on a const; Change this to a range that filesort
......
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