Commit df693095 authored by serg@serg.mylan's avatar serg@serg.mylan

MATCH ... AGAINST ("..." WITH QUERY EXPANSION) syntax

parent 85942f14
...@@ -57,9 +57,12 @@ extern const char *ft_boolean_syntax; ...@@ -57,9 +57,12 @@ extern const char *ft_boolean_syntax;
int ft_init_stopwords(void); int ft_init_stopwords(void);
void ft_free_stopwords(void); void ft_free_stopwords(void);
#define FT_NL 0 #define FT_NL 0 /* this MUST be 0, see ft_init_search() */
#define FT_BOOL 1 #define FT_BOOL 1 /* this MUST be 1, see ft_init_search() */
FT_INFO *ft_init_search(uint,void *, uint, byte *, uint, my_bool); #define FT_SORTED 2
#define FT_EXPAND 4 /* query expansion */
FT_INFO *ft_init_search(uint,void *, uint, byte *, uint);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -341,7 +341,7 @@ static void _ftb_init_index_search(FT_INFO *ftb) ...@@ -341,7 +341,7 @@ static void _ftb_init_index_search(FT_INFO *ftb)
FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query, FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
uint query_len, uint query_len,
my_bool presort __attribute__((unused))) uint flags __attribute__((unused)))
{ {
FTB *ftb; FTB *ftb;
FTB_EXPR *ftbe; FTB_EXPR *ftbe;
......
...@@ -175,7 +175,7 @@ static int FT_DOC_cmp(FT_DOC *a, FT_DOC *b) ...@@ -175,7 +175,7 @@ static int FT_DOC_cmp(FT_DOC *a, FT_DOC *b)
FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query, FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query,
uint query_len, my_bool presort) uint query_len, uint flags)
{ {
TREE allocated_wtree, *wtree=&allocated_wtree; TREE allocated_wtree, *wtree=&allocated_wtree;
ALL_IN_ONE aio; ALL_IN_ONE aio;
...@@ -224,7 +224,7 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query, ...@@ -224,7 +224,7 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query,
tree_walk(&aio.dtree, (tree_walk_action) &walk_and_copy, tree_walk(&aio.dtree, (tree_walk_action) &walk_and_copy,
&dptr, left_root_right); &dptr, left_root_right);
if (presort) if (flags & FT_SORTED)
qsort(dlist->doc, dlist->ndocs, sizeof(FT_DOC), (qsort_cmp)&FT_DOC_cmp); qsort(dlist->doc, dlist->ndocs, sizeof(FT_DOC), (qsort_cmp)&FT_DOC_cmp);
err2: err2:
......
...@@ -53,14 +53,14 @@ const struct _ft_vft _ft_vft_boolean = { ...@@ -53,14 +53,14 @@ const struct _ft_vft _ft_vft_boolean = {
ft_boolean_get_relevance, ft_boolean_reinit_search ft_boolean_get_relevance, ft_boolean_reinit_search
}; };
FT_INFO *(*_ft_init_vft[2])(MI_INFO *, uint, byte *, uint, my_bool) = FT_INFO *(*_ft_init_vft[2])(MI_INFO *, uint, byte *, uint, uint) =
{ ft_init_nlq_search, ft_init_boolean_search }; { ft_init_nlq_search, ft_init_boolean_search };
FT_INFO *ft_init_search(uint mode, void *info, uint keynr, FT_INFO *ft_init_search(uint flags, void *info, uint keynr,
byte *query, uint query_len, my_bool presort) byte *query, uint query_len)
{ {
return (*_ft_init_vft[mode])((MI_INFO *)info, keynr, return (*_ft_init_vft[ flags&1 ])((MI_INFO *)info, keynr,
query, query_len, presort); query, query_len, flags);
} }
const char *ft_stopword_file = 0; const char *ft_stopword_file = 0;
......
...@@ -128,7 +128,7 @@ FT_WORD * _mi_ft_parserecord(MI_INFO *, uint, const byte *); ...@@ -128,7 +128,7 @@ FT_WORD * _mi_ft_parserecord(MI_INFO *, uint, const byte *);
uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record); uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record);
extern const struct _ft_vft _ft_vft_nlq; extern const struct _ft_vft _ft_vft_nlq;
FT_INFO *ft_init_nlq_search(MI_INFO *, uint, byte *, uint, my_bool); FT_INFO *ft_init_nlq_search(MI_INFO *, uint, byte *, uint, uint);
int ft_nlq_read_next(FT_INFO *, char *); int ft_nlq_read_next(FT_INFO *, char *);
float ft_nlq_find_relevance(FT_INFO *, byte *, uint); float ft_nlq_find_relevance(FT_INFO *, byte *, uint);
void ft_nlq_close_search(FT_INFO *); void ft_nlq_close_search(FT_INFO *);
...@@ -137,7 +137,7 @@ my_off_t ft_nlq_get_docid(FT_INFO *); ...@@ -137,7 +137,7 @@ my_off_t ft_nlq_get_docid(FT_INFO *);
void ft_nlq_reinit_search(FT_INFO *); void ft_nlq_reinit_search(FT_INFO *);
extern const struct _ft_vft _ft_vft_boolean; extern const struct _ft_vft _ft_vft_boolean;
FT_INFO *ft_init_boolean_search(MI_INFO *, uint, byte *, uint, my_bool); FT_INFO *ft_init_boolean_search(MI_INFO *, uint, byte *, uint, uint);
int ft_boolean_read_next(FT_INFO *, char *); int ft_boolean_read_next(FT_INFO *, char *);
float ft_boolean_find_relevance(FT_INFO *, byte *, uint); float ft_boolean_find_relevance(FT_INFO *, byte *, uint);
void ft_boolean_close_search(FT_INFO *); void ft_boolean_close_search(FT_INFO *);
......
...@@ -272,7 +272,7 @@ int _mi_ck_write_btree(register MI_INFO *info, uint keynr, uchar *key, ...@@ -272,7 +272,7 @@ int _mi_ck_write_btree(register MI_INFO *info, uint keynr, uchar *key,
if (!error) if (!error)
error= _mi_ft_convert_to_ft2(info, keynr, key); error= _mi_ft_convert_to_ft2(info, keynr, key);
delete_dynamic(info->ft1_to_ft2); delete_dynamic(info->ft1_to_ft2);
my_free(info->ft1_to_ft2, MYF(0)); my_free((gptr)info->ft1_to_ft2, MYF(0));
info->ft1_to_ft2=0; info->ft1_to_ft2=0;
} }
DBUG_RETURN(error); DBUG_RETURN(error);
......
...@@ -130,9 +130,9 @@ select * from t2 having MATCH inhalt AGAINST ('foobar'); ...@@ -130,9 +130,9 @@ select * from t2 having MATCH inhalt AGAINST ('foobar');
# check of fulltext errors # check of fulltext errors
# #
--error 1279 --error 1280
CREATE TABLE t3 (t int(11),i text,fulltext tix (t,i)); CREATE TABLE t3 (t int(11),i text,fulltext tix (t,i));
--error 1279 --error 1280
CREATE TABLE t3 (t int(11),i text, CREATE TABLE t3 (t int(11),i text,
j varchar(200) CHARACTER SET latin2, j varchar(200) CHARACTER SET latin2,
fulltext tix (i,j)); fulltext tix (i,j));
......
...@@ -89,9 +89,8 @@ class ha_myisam: public handler ...@@ -89,9 +89,8 @@ class ha_myisam: public handler
ft_handler->please->reinit_search(ft_handler); ft_handler->please->reinit_search(ft_handler);
return 0; return 0;
} }
FT_INFO *ft_init_ext(uint mode, uint inx,const byte *key, uint keylen, FT_INFO *ft_init_ext(uint flags, uint inx,const byte *key, uint keylen)
bool presort) { return ft_init_search(flags,file,inx,(byte*) key,keylen); }
{ return ft_init_search(mode, file,inx,(byte*) key,keylen,presort); }
int ft_read(byte *buf); int ft_read(byte *buf);
int rnd_init(bool scan=1); int rnd_init(bool scan=1);
int rnd_next(byte *buf); int rnd_next(byte *buf);
......
...@@ -271,8 +271,7 @@ public: ...@@ -271,8 +271,7 @@ public:
} }
virtual int ft_init() virtual int ft_init()
{ return -1; } { return -1; }
virtual FT_INFO *ft_init_ext(uint mode,uint inx,const byte *key, uint keylen, virtual FT_INFO *ft_init_ext(uint flags,uint inx,const byte *key, uint keylen)
bool presort)
{ return NULL; } { return NULL; }
virtual int ft_read(byte *buf) { return -1; } virtual int ft_read(byte *buf) { return -1; }
virtual int rnd_init(bool scan=1)=0; virtual int rnd_init(bool scan=1)=0;
......
...@@ -2587,10 +2587,10 @@ void Item_func_match::init_search(bool no_order) ...@@ -2587,10 +2587,10 @@ void Item_func_match::init_search(bool no_order)
ft_tmp= &search_value; ft_tmp= &search_value;
} }
ft_handler=table->file->ft_init_ext(mode, key, if (join_key && !no_order) flags|=FT_SORTED;
ft_handler=table->file->ft_init_ext(flags, key,
(byte*) ft_tmp->ptr(), (byte*) ft_tmp->ptr(),
ft_tmp->length(), ft_tmp->length());
join_key && !no_order);
if (join_key) if (join_key)
table->file->ft_handler=ft_handler; table->file->ft_handler=ft_handler;
...@@ -2631,7 +2631,7 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) ...@@ -2631,7 +2631,7 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
/* check that all columns come from the same table */ /* check that all columns come from the same table */
if (my_count_bits(used_tables_cache) != 1) if (my_count_bits(used_tables_cache) != 1)
key=NO_SUCH_KEY; key=NO_SUCH_KEY;
if (key == NO_SUCH_KEY && mode != FT_BOOL) if (key == NO_SUCH_KEY && !(flags & FT_BOOL))
{ {
my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH"); my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH");
return 1; return 1;
...@@ -2711,7 +2711,7 @@ bool Item_func_match::fix_index() ...@@ -2711,7 +2711,7 @@ bool Item_func_match::fix_index()
} }
err: err:
if (mode == FT_BOOL) if (flags & FT_BOOL)
{ {
key=NO_SUCH_KEY; key=NO_SUCH_KEY;
return 0; return 0;
...@@ -2723,8 +2723,8 @@ err: ...@@ -2723,8 +2723,8 @@ err:
bool Item_func_match::eq(const Item *item, bool binary_cmp) const bool Item_func_match::eq(const Item *item, bool binary_cmp) const
{ {
if (item->type() != FUNC_ITEM || if (item->type() != FUNC_ITEM || ((Item_func*)item)->functype() != FT_FUNC ||
func_name() != ((Item_func*)item)->func_name()) flags != ((Item_func_match*)item)->flags)
return 0; return 0;
Item_func_match *ifm=(Item_func_match*) item; Item_func_match *ifm=(Item_func_match*) item;
......
...@@ -962,7 +962,7 @@ public: ...@@ -962,7 +962,7 @@ public:
class Item_func_match :public Item_real_func class Item_func_match :public Item_real_func
{ {
public: public:
uint key, mode; uint key, flags;
bool join_key; bool join_key;
DTCollation cmp_collation; DTCollation cmp_collation;
FT_INFO *ft_handler; FT_INFO *ft_handler;
...@@ -972,7 +972,7 @@ public: ...@@ -972,7 +972,7 @@ public:
String value; // value of concat String value; // value of concat
String search_value; // key_item()'s value converted to cmp_collation String search_value; // key_item()'s value converted to cmp_collation
Item_func_match(List<Item> &a): Item_real_func(a), Item_func_match(List<Item> &a, uint b): Item_real_func(a), flags(b),
table(0), master(0), ft_handler(0), concat(0), key(0), join_key(0) { } table(0), master(0), ft_handler(0), concat(0), key(0), join_key(0) { }
~Item_func_match() ~Item_func_match()
{ {
...@@ -988,6 +988,7 @@ public: ...@@ -988,6 +988,7 @@ public:
delete concat; delete concat;
} }
enum Functype functype() const { return FT_FUNC; } enum Functype functype() const { return FT_FUNC; }
const char *func_name() const { return "match"; }
void update_used_tables() {} void update_used_tables() {}
table_map not_null_tables() const { return 0; } table_map not_null_tables() const { return 0; }
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref); bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
...@@ -1000,22 +1001,6 @@ public: ...@@ -1000,22 +1001,6 @@ public:
}; };
class Item_func_match_nl :public Item_func_match
{
public:
Item_func_match_nl(List<Item> &a) :Item_func_match(a) { mode=FT_NL; }
const char *func_name() const { return "match_nl"; }
};
class Item_func_match_bool :public Item_func_match
{
public:
Item_func_match_bool(List<Item> &a) :Item_func_match(a) { mode=FT_BOOL; }
const char *func_name() const { return "match_bool"; }
};
class Item_func_bit_xor : public Item_int_func class Item_func_bit_xor : public Item_int_func
{ {
public: public:
......
...@@ -153,6 +153,7 @@ static SYMBOL symbols[] = { ...@@ -153,6 +153,7 @@ static SYMBOL symbols[] = {
{ "EXECUTE", SYM(EXECUTE_SYM),0,0}, { "EXECUTE", SYM(EXECUTE_SYM),0,0},
{ "EXPLAIN", SYM(DESCRIBE),0,0}, { "EXPLAIN", SYM(DESCRIBE),0,0},
{ "EXISTS", SYM(EXISTS),0,0}, { "EXISTS", SYM(EXISTS),0,0},
{ "EXPANSION", SYM(EXPANSION_SYM),0,0},
{ "EXTENDED", SYM(EXTENDED_SYM),0,0}, { "EXTENDED", SYM(EXTENDED_SYM),0,0},
{ "FAST", SYM(FAST_SYM),0,0}, { "FAST", SYM(FAST_SYM),0,0},
{ "FIELDS", SYM(COLUMNS),0,0}, { "FIELDS", SYM(COLUMNS),0,0},
......
...@@ -135,6 +135,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -135,6 +135,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token DROP %token DROP
%token EVENTS_SYM %token EVENTS_SYM
%token EXECUTE_SYM %token EXECUTE_SYM
%token EXPANSION_SYM
%token FLUSH_SYM %token FLUSH_SYM
%token HELP_SYM %token HELP_SYM
%token INSERT %token INSERT
...@@ -168,7 +169,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -168,7 +169,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token SUPER_SYM %token SUPER_SYM
%token TRUNCATE_SYM %token TRUNCATE_SYM
%token UNLOCK_SYM %token UNLOCK_SYM
%token UNTIL_SYM %token UNTIL_SYM
%token UPDATE_SYM %token UPDATE_SYM
%token ACTION %token ACTION
...@@ -604,8 +605,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -604,8 +605,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <num> %type <num>
type int_type real_type order_dir opt_field_spec lock_option type int_type real_type order_dir opt_field_spec lock_option
udf_type if_exists opt_local opt_table_options table_options udf_type if_exists opt_local opt_table_options table_options
table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type opt_var_ident_type table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type
delete_option opt_temporary all_or_any opt_distinct opt_ignore_leaves opt_var_ident_type delete_option opt_temporary all_or_any opt_distinct
opt_ignore_leaves fulltext_options
%type <ulong_num> %type <ulong_num>
ULONG_NUM raid_types merge_insert_types ULONG_NUM raid_types merge_insert_types
...@@ -2448,14 +2450,10 @@ simple_expr: ...@@ -2448,14 +2450,10 @@ simple_expr:
| EXISTS exists_subselect { $$= $2; } | EXISTS exists_subselect { $$= $2; }
| singlerow_subselect { $$= $1; } | singlerow_subselect { $$= $1; }
| '{' ident expr '}' { $$= $3; } | '{' ident expr '}' { $$= $3; }
| MATCH ident_list_arg AGAINST '(' expr ')' | MATCH ident_list_arg AGAINST '(' expr fulltext_options ')'
{ $2->push_front($5); { $2->push_front($5);
Select->add_ftfunc_to_list((Item_func_match *) Select->add_ftfunc_to_list((Item_func_match*)
($$=new Item_func_match_nl(*$2))); } ($$=new Item_func_match(*$2,$6))); }
| MATCH ident_list_arg AGAINST '(' expr IN_SYM BOOLEAN_SYM MODE_SYM ')'
{ $2->push_front($5);
Select->add_ftfunc_to_list((Item_func_match *)
($$=new Item_func_match_bool(*$2))); }
| ASCII_SYM '(' expr ')' { $$= new Item_func_ascii($3); } | ASCII_SYM '(' expr ')' { $$= new Item_func_ascii($3); }
| BINARY expr %prec NEG | BINARY expr %prec NEG
{ {
...@@ -2843,6 +2841,12 @@ simple_expr: ...@@ -2843,6 +2841,12 @@ simple_expr:
| EXTRACT_SYM '(' interval FROM expr ')' | EXTRACT_SYM '(' interval FROM expr ')'
{ $$=new Item_extract( $3, $5); }; { $$=new Item_extract( $3, $5); };
fulltext_options:
/* nothing */ { $$= FT_NL; }
| WITH QUERY_SYM EXPANSION_SYM { $$= FT_NL | FT_EXPAND; }
| IN_SYM BOOLEAN_SYM MODE_SYM { $$= FT_BOOL; }
;
udf_expr_list: udf_expr_list:
/* empty */ { $$= NULL; } /* empty */ { $$= NULL; }
| expr_list { $$= $1;}; | expr_list { $$= $1;};
......
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