summaryrefslogtreecommitdiff
path: root/myisam/ft_update.c
diff options
context:
space:
mode:
Diffstat (limited to 'myisam/ft_update.c')
-rw-r--r--myisam/ft_update.c71
1 files changed, 68 insertions, 3 deletions
diff --git a/myisam/ft_update.c b/myisam/ft_update.c
index 658ea9282f3..f8f1d7769aa 100644
--- a/myisam/ft_update.c
+++ b/myisam/ft_update.c
@@ -29,14 +29,16 @@
/* parses a document i.e. calls _mi_ft_parse for every keyseg */
-static FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, byte *keybuf,
+FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, byte *keybuf,
const byte *record)
{
- TREE *parsed=NULL;
+ TREE *parsed, ptree;
MI_KEYSEG *keyseg;
byte *pos;
uint i;
+ bzero(parsed=&ptree, sizeof(ptree));
+
keyseg=info->s->keyinfo[keynr].seg;
for (i=info->s->keyinfo[keynr].keysegs-FT_SEGS ; i-- ; )
{
@@ -64,7 +66,7 @@ static FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, byte *keybuf,
return NULL;
}
/* Handle the case where all columns are NULL */
- if (!parsed && !(parsed=ft_parse(0, (byte*) "", 0)))
+ if (!is_tree_inited(parsed) && !(parsed=ft_parse(parsed, (byte*) "", 0)))
return NULL;
return ft_linearize(info, keynr, keybuf, parsed);
}
@@ -151,6 +153,69 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2)
return GEE_THEY_ARE_ABSOLUTELY_IDENTICAL;
}
+/* update a document entry */
+int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf,
+ const byte *oldrec, const byte *newrec, my_off_t pos)
+{
+ int error= -1;
+ FT_WORD *oldlist,*newlist, *old_word, *new_word;
+ uint key_length;
+ uint cmp;
+
+ if (!(old_word=oldlist=_mi_ft_parserecord(info, keynr, keybuf, oldrec)))
+ goto err0;
+ if (!(new_word=newlist=_mi_ft_parserecord(info, keynr, keybuf, newrec)))
+ goto err1;
+
+ while(old_word->pos && new_word->pos)
+ {
+ cmp=_mi_compare_text(default_charset_info,
+ (uchar*) old_word->pos,old_word->len,
+ (uchar*) new_word->pos,new_word->len,0);
+ if (cmp==0)
+ {
+ double p=(old_word->weight-new_word->weight)/
+ (old_word->weight+new_word->weight);
+ if (p<1e-5)
+ cmp=0;
+ else
+ cmp=sgn(p);
+ }
+ else
+ cmp=sgn(cmp);
+
+ switch (cmp) {
+ case -1:
+ key_length=_ft_make_key(info,keynr,keybuf,old_word,pos);
+ if (error=_mi_ck_delete(info,keynr,(uchar*) keybuf,key_length))
+ goto err2;
+ old_word++;
+ break;
+ case 0:
+ old_word++;
+ new_word++;
+ break;
+ case 1:
+ key_length=_ft_make_key(info,keynr,keybuf,new_word,pos);
+ if (error=_mi_ck_write(info,keynr,(uchar*) keybuf,key_length))
+ goto err2;
+ new_word++;
+ break;
+ }
+ }
+ if (old_word->pos)
+ error=_mi_ft_erase(info,keynr,keybuf,old_word,pos);
+ else if (new_word->pos)
+ error=_mi_ft_store(info,keynr,keybuf,new_word,pos);
+
+err2:
+ my_free((char*) newlist,MYF(0));
+err1:
+ my_free((char*) oldlist,MYF(0));
+err0:
+ return error;
+}
+
/* adds a document to the collection */
int _mi_ft_add(MI_INFO *info, uint keynr, byte *keybuf, const byte *record,
my_off_t pos)