MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Sergei Golubchik Date:April 6 2006 2:03pm
Subject:bk commit into 5.1 tree (serg:1.2292) BUG#18836
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of serg. When serg does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2292 06/04/06 16:03:04 serg@stripped +5 -0
  Bug#18836 - fulltext parser plugin is called recursively.
  Don't use the same param in recursive call.
  Also, the fix makes it safe for a plugin to replace param->mysql_add_word

  storage/myisam/ftdefs.h
    1.36 06/04/06 16:02:51 serg@stripped +2 -1
    Bug#18836 - fulltext parser plugin is called recursively.
    Don't use the same param in recursive call.

  storage/myisam/ft_update.c
    1.42 06/04/06 16:02:51 serg@stripped +1 -1
    Bug#18836 - fulltext parser plugin is called recursively.
    Don't use the same param in recursive call.

  storage/myisam/ft_parser.c
    1.52 06/04/06 16:02:51 serg@stripped +33 -16
    Bug#18836 - fulltext parser plugin is called recursively.
    Don't use the same param in recursive call.
    Also, the fix makes it safe for a plugin to replace param->mysql_add_word

  storage/myisam/ft_nlq_search.c
    1.43 06/04/06 16:02:51 serg@stripped +1 -1
    Bug#18836 - fulltext parser plugin is called recursively.
    Don't use the same param in recursive call.

  storage/myisam/ft_boolean_search.c
    1.100 06/04/06 16:02:51 serg@stripped +23 -16
    Bug#18836 - fulltext parser plugin is called recursively.
    Don't use the same param in recursive call.
    Also, the fix makes it safe for a plugin to replace param->mysql_add_word

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	serg
# Host:	serg.mylan
# Root:	/usr/home/serg/Abk/mysql-5.1

--- 1.51/storage/myisam/ft_parser.c	Wed Dec 28 13:05:20 2005
+++ 1.52/storage/myisam/ft_parser.c	Thu Apr  6 16:02:51 2006
@@ -27,6 +27,7 @@ typedef struct st_ft_docstat {
 
 typedef struct st_my_ft_parser_param
 {
+  MYSQL_FTPARSER_PARAM *up;
   TREE *wtree;
   my_bool with_alloc;
 } MY_FT_PARSER_PARAM;
@@ -268,16 +269,16 @@ static int ft_add_word(void *param, byte
 }
 
 
-static int ft_parse_internal(void *param, byte *doc, uint doc_len)
+static int ft_parse_internal(void *param, byte *doc, int doc_len)
 {
   byte   *end=doc+doc_len;
+  MY_FT_PARSER_PARAM *ft_param=(MY_FT_PARSER_PARAM *)param;
+  TREE *wtree= ft_param->wtree;
   FT_WORD w;
-  TREE *wtree;
   DBUG_ENTER("ft_parse_internal");
 
-  wtree= ((MY_FT_PARSER_PARAM *)param)->wtree;
   while (ft_simple_get_word(wtree->custom_arg, &doc, end, &w, TRUE))
-    if (ft_add_word(param, w.pos, w.len, 0))
+    if (ft_param->up->mysql_add_word(param, w.pos, w.len, 0))
       DBUG_RETURN(1);
   DBUG_RETURN(0);
 }
@@ -290,6 +291,8 @@ int ft_parse(TREE *wtree, byte *doc, int
   MY_FT_PARSER_PARAM my_param;
   DBUG_ENTER("ft_parse");
   DBUG_ASSERT(parser);
+
+  my_param.up= param;
   my_param.wtree= wtree;
   my_param.with_alloc= with_alloc;
 
@@ -300,11 +303,12 @@ int ft_parse(TREE *wtree, byte *doc, int
   param->doc= doc;
   param->length= doclen;
   param->mode= MYSQL_FTPARSER_SIMPLE_MODE;
-  DBUG_RETURN(parser->parse(param));  
+  DBUG_RETURN(parser->parse(param));
 }
 
-
-MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info, uint keynr)
+#define MAX_PARAM_NR 2
+MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info,
+                                                uint keynr, uint paramnr)
 {
   uint32 ftparser_nr;
   struct st_mysql_ftparser *parser;
@@ -343,8 +347,14 @@ MYSQL_FTPARSER_PARAM *ftparser_call_init
       }
       info->s->ftparsers= ftparsers;
     }
+    /*
+      We have to allocate two MYSQL_FTPARSER_PARAM structures per plugin
+      because in a boolean search a parser is called recursively
+      ftb_find_relevance* calls ftb_check_phrase*
+      (MAX_PARAM_NR=2)
+    */
     info->ftparser_param= (MYSQL_FTPARSER_PARAM *)
-      my_malloc(sizeof(MYSQL_FTPARSER_PARAM) *
+      my_malloc(MAX_PARAM_NR * sizeof(MYSQL_FTPARSER_PARAM) *
                 info->s->ftparsers, MYF(MY_WME|MY_ZEROFILL));
     if (! info->ftparser_param)
       return 0;
@@ -359,6 +369,8 @@ MYSQL_FTPARSER_PARAM *ftparser_call_init
     ftparser_nr= info->s->keyinfo[keynr].ftparser_nr;
     parser= info->s->keyinfo[keynr].parser;
   }
+  DBUG_ASSERT(paramnr < MAX_PARAM_NR);
+  ftparser_nr= ftparser_nr*MAX_PARAM_NR + paramnr;
   if (! info->ftparser_param[ftparser_nr].mysql_add_word)
   {
     /* Note, that mysql_add_word is used here as a flag:
@@ -372,22 +384,27 @@ MYSQL_FTPARSER_PARAM *ftparser_call_init
   return &info->ftparser_param[ftparser_nr];
 }
 
-
 void ftparser_call_deinitializer(MI_INFO *info)
 {
-  uint i, keys= info->s->state.header.keys;
+  uint i, j, keys= info->s->state.header.keys;
   if (! info->ftparser_param)
     return;
   for (i= 0; i < keys; i++)
   {
     MI_KEYDEF *keyinfo= &info->s->keyinfo[i];
-    MYSQL_FTPARSER_PARAM *ftparser_param=
-      &info->ftparser_param[keyinfo->ftparser_nr];
-    if (keyinfo->flag & HA_FULLTEXT && ftparser_param->mysql_add_word)
+    for (j=0; j < MAX_PARAM_NR; j++)
     {
-      if (keyinfo->parser->deinit)
-        keyinfo->parser->deinit(ftparser_param);
-      ftparser_param->mysql_add_word= 0;
+      MYSQL_FTPARSER_PARAM *ftparser_param=
+        &info->ftparser_param[keyinfo->ftparser_nr*MAX_PARAM_NR + j];
+      if (keyinfo->flag & HA_FULLTEXT && ftparser_param->mysql_add_word)
+      {
+        if (keyinfo->parser->deinit)
+          keyinfo->parser->deinit(ftparser_param);
+        ftparser_param->mysql_add_word= 0;
+      }
+      else
+        break;
     }
   }
 }
+

--- 1.41/storage/myisam/ft_update.c	Thu Feb  2 21:20:21 2006
+++ 1.42/storage/myisam/ft_update.c	Thu Apr  6 16:02:51 2006
@@ -122,7 +122,7 @@ FT_WORD * _mi_ft_parserecord(MI_INFO *in
   TREE ptree;
   MYSQL_FTPARSER_PARAM *param;
   DBUG_ENTER("_mi_ft_parserecord");
-  if (! (param= ftparser_call_initializer(info, keynr)))
+  if (! (param= ftparser_call_initializer(info, keynr, 0)))
     DBUG_RETURN(NULL);
   bzero((char*) &ptree, sizeof(ptree));
   if (_mi_ft_parse(&ptree, info, keynr, record, 0, param))

--- 1.35/storage/myisam/ftdefs.h	Tue Feb 14 10:51:20 2006
+++ 1.36/storage/myisam/ftdefs.h	Thu Apr  6 16:02:51 2006
@@ -145,5 +145,6 @@ float ft_boolean_get_relevance(FT_INFO *
 my_off_t ft_boolean_get_docid(FT_INFO *);
 void ft_boolean_reinit_search(FT_INFO *);
 extern MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info,
-                                                       uint keynr);
+                                                       uint keynr,
+                                                       uint paramnr);
 extern void ftparser_call_deinitializer(MI_INFO *info);

--- 1.99/storage/myisam/ft_boolean_search.c	Mon Jan 30 13:28:42 2006
+++ 1.100/storage/myisam/ft_boolean_search.c	Thu Apr  6 16:02:51 2006
@@ -160,6 +160,7 @@ static int FTB_WORD_cmp_list(CHARSET_INF
 
 typedef struct st_my_ftb_param
 {
+  MYSQL_FTPARSER_PARAM *up;
   FTB *ftb;
   FTB_EXPR *ftbe;
   byte *up_quot;
@@ -280,7 +281,7 @@ static int ftb_parse_query_internal(void
   info.prev= ' ';
   info.quot= 0;
   while (ft_get_word(cs, start, end, &w, &info))
-    ftb_query_add_word(param, w.pos, w.len, &info);
+    ftb_param->up->mysql_add_word(param, w.pos, w.len, &info);
   return(0);
 }
 
@@ -295,14 +296,15 @@ static void _ftb_parse_query(FTB *ftb, b
 
   if (ftb->state != UNINITIALIZED)
     DBUG_VOID_RETURN;
+  if (! (param= ftparser_call_initializer(ftb->info, ftb->keynr, 0)))
+    DBUG_VOID_RETURN;
 
+  ftb_param.up= param;
   ftb_param.ftb= ftb;
   ftb_param.depth= 0;
   ftb_param.ftbe= ftb->root;
   ftb_param.up_quot= 0;
 
-  if (! (param= ftparser_call_initializer(ftb->info, ftb->keynr)))
-    DBUG_VOID_RETURN;
   param->mysql_parse= ftb_parse_query_internal;
   param->mysql_add_word= ftb_query_add_word;
   param->mysql_ftparam= (void *)&ftb_param;
@@ -313,7 +315,7 @@ static void _ftb_parse_query(FTB *ftb, b
   parser->parse(param);
   DBUG_VOID_RETURN;
 }
- 
+
 
 static int _ftb_no_dupes_cmp(void* not_used __attribute__((unused)),
                              const void *a,const void *b)
@@ -569,6 +571,7 @@ err:
 
 typedef struct st_my_ftb_phrase_param
 {
+  MYSQL_FTPARSER_PARAM *up;
   LIST *phrase;
   LIST *document;
   CHARSET_INFO *cs;
@@ -615,7 +618,7 @@ static int ftb_check_phrase_internal(voi
   const char *docend= document + len;
   while (ft_simple_get_word(phrase_param->cs, &document, docend, &word, FALSE))
   {
-    ftb_phrase_add_word(param, word.pos, word.len, 0);
+    phrase_param->up->mysql_add_word(param, word.pos, word.len, 0);
     if (phrase_param->match)
       return 1;
   }
@@ -644,8 +647,11 @@ static int _ftb_check_phrase(FTB *ftb, c
   MYSQL_FTPARSER_PARAM *param;
   DBUG_ENTER("_ftb_check_phrase");
   DBUG_ASSERT(parser);
-  if (! (param= ftparser_call_initializer(ftb->info, ftb->keynr)))
+
+  if (! (param= ftparser_call_initializer(ftb->info, ftb->keynr, 1)))
     DBUG_RETURN(0);
+
+  ftb_param.up= param;
   ftb_param.phrase= ftbe->phrase;
   ftb_param.document= ftbe->document;
   ftb_param.cs= ftb->charset;
@@ -814,6 +820,7 @@ err:
 
 typedef struct st_my_ftb_find_param
 {
+  MYSQL_FTPARSER_PARAM *up;
   FT_INFO *ftb;
   FT_SEG_ITERATOR *ftsi;
 } MY_FTB_FIND_PARAM;
@@ -854,11 +861,12 @@ static int ftb_find_relevance_add_word(v
 
 static int ftb_find_relevance_parse(void *param, char *doc, int len)
 {
-  FT_INFO *ftb= ((MY_FTB_FIND_PARAM *)param)->ftb;
+  MY_FTB_FIND_PARAM *ftb_param=(MY_FTB_FIND_PARAM *)param;
+  FT_INFO *ftb= ftb_param->ftb;
   char *end= doc + len;
   FT_WORD w;
   while (ft_simple_get_word(ftb->charset, &doc, end, &w, TRUE))
-    ftb_find_relevance_add_word(param, w.pos, w.len, 0);
+    ftb_param->up->mysql_add_word(param, w.pos, w.len, 0);
   return(0);
 }
 
@@ -878,7 +886,7 @@ float ft_boolean_find_relevance(FT_INFO 
     return -2.0;
   if (!ftb->queue.elements)
     return 0;
-  if (! (param= ftparser_call_initializer(ftb->info, ftb->keynr)))
+  if (! (param= ftparser_call_initializer(ftb->info, ftb->keynr, 0)))
     return 0;
 
   if (ftb->state != INDEX_SEARCH && docid <= ftb->lastpos)
@@ -902,19 +910,18 @@ float ft_boolean_find_relevance(FT_INFO 
     _mi_ft_segiterator_init(ftb->info, ftb->keynr, record, &ftsi);
   memcpy(&ftsi2, &ftsi, sizeof(ftsi));
 
+  ftb_param.up= param;
   ftb_param.ftb= ftb;
   ftb_param.ftsi= &ftsi2;
+  param->mysql_parse= ftb_find_relevance_parse;
+  param->mysql_add_word= ftb_find_relevance_add_word;
+  param->mysql_ftparam= (void *)&ftb_param;
+  param->cs= ftb->charset;
+  param->mode= MYSQL_FTPARSER_SIMPLE_MODE;
   while (_mi_ft_segiterator(&ftsi))
   {
     if (!ftsi.pos)
       continue;
-    /* Since subsequent call to _ftb_check_phrase overwrites param elements,
-       it must be reinitialized at each iteration _inside_ the loop. */
-    param->mysql_parse= ftb_find_relevance_parse;
-    param->mysql_add_word= ftb_find_relevance_add_word;
-    param->mysql_ftparam= (void *)&ftb_param;
-    param->cs= ftb->charset;
-    param->mode= MYSQL_FTPARSER_SIMPLE_MODE;
     param->doc= (byte *)ftsi.pos;
     param->length= ftsi.len;
     parser->parse(param);

--- 1.42/storage/myisam/ft_nlq_search.c	Wed Dec 28 13:05:20 2005
+++ 1.43/storage/myisam/ft_nlq_search.c	Thu Apr  6 16:02:51 2006
@@ -226,7 +226,7 @@ FT_INFO *ft_init_nlq_search(MI_INFO *inf
   aio.charset=info->s->keyinfo[keynr].seg->charset;
   aio.keybuff=info->lastkey+info->s->base.max_key_length;
   parser= info->s->keyinfo[keynr].parser;
-  if (! (ftparser_param= ftparser_call_initializer(info, keynr)))
+  if (! (ftparser_param= ftparser_call_initializer(info, keynr, 0)))
     goto err;
 
   bzero(&wtree,sizeof(wtree));
Thread
bk commit into 5.1 tree (serg:1.2292) BUG#18836Sergei Golubchik6 Apr