Branch: Tag:

2002-05-15

2002-05-15 14:28:53 by Mattias Andersson <matan@lysator.liu.se>

Backport of glob search from 2.4.

Rev: lib/modules/Search.pmod/Database.pmod/MySQL.pike:1.73
Rev: lib/modules/Search.pmod/Grammar.pmod/DefaultParser.pike:1.8
Rev: lib/modules/Search.pmod/Query.pmod:1.24

1:   // This file is part of Roxen Search   // Copyright © 2001 Roxen IS. All rights reserved.   // - // $Id: Query.pmod,v 1.23 2001/09/25 22:02:37 js Exp $ + // $Id: Query.pmod,v 1.24 2002/05/15 14:28:53 mattias Exp $      static function(string,int:string) blobfeeder(Search.Database.Base db, array words)   {
109:    specialRanking = defaultRanking->copy();    }    +  static array(array(string)) split_words(array(string) words) +  { +  array a=({}),b=({}); +  foreach(words, string word) +  if(has_value(word, "*") || has_value(word, "?")) +  b+=({ word }); +  else +  a+=({ word }); +  return ({ a, b }); +  } +     static constant ParseNode = Search.Grammar.ParseNode;       static array(array(string)|string) words = ({ });
132:    }       void exec(ParseNode q) { +  int max_globs = 100;    switch (q->op) {    case "and":    {
174:    {    Search.RankingProfile ranking = defaultRanking;    -  if (q->field != "any") { +  if (q->field != "any") +  {    ranking = specialRanking;    int fieldID = db->get_field_id(q->field, 1); -  if (!fieldID && q->field != "body") { +  if (!fieldID && q->field != "body") +  {    // There was no such field, so we push an empty ResultSet !    push(Search.ResultSet());    break;
186:    ranking->field_ranking[fieldID] = 1;    }    +  [array plusWords, array plusWordGlobs] = split_words(q->plusWords); +  [array ordinaryWords, array ordinaryWordGlobs] = split_words(q->words); +  [array minusWords, array minusWordGlobs] = split_words(q->minusWords); +  + // werror("[%-10s] plus: %-15s ordinary: %-15s minus: %-15s\n", q->field, q>plusWords*", ", q->words*", ", q->minusWords*", "); +     int hasPlus = sizeof(q->plusWords) || sizeof(q->plusPhrases);    int hasOrdinary = sizeof(q->words) || sizeof(q->phrases);    int hasMinus = sizeof(q->minusWords) || sizeof(q->minusPhrases); -  if (hasPlus) { +  +  if(hasPlus) +  {    int first = 1; -  if (sizeof(q->plusWords)) { -  words += q->plusWords; -  push(do_query_and(db, q->plusWords, ranking)); +  if(sizeof(plusWords)) +  { +  words += plusWords; +  push(do_query_and(db, plusWords, ranking));    first = 0;    } -  foreach (q->plusPhrases, array(string) ph) { +  foreach(plusWordGlobs, string plusWordGlob) +  { +  push(do_query_or(db, db->expand_word_glob(plusWordGlob, max_globs), ranking)); +  if (!first) +  { +  Search.ResultSet r2 = pop(); +  Search.ResultSet r1 = pop(); +  push(r1 & r2); +  } +  first = 0; +  } +  foreach (q->plusPhrases, array(string) ph) +  {    words += ph;    push(do_query_phrase(db, ph, ranking)); -  if (!first) { +  if (!first) +  {    Search.ResultSet r2 = pop();    Search.ResultSet r1 = pop();    push(r1 & r2);
207:    first = 0;    }    } -  if (hasOrdinary) { +  +  if(hasOrdinary) +  {    int first = 1; -  if (sizeof(q->words)) { -  words += q->words; -  push(do_query_or(db, q->words, ranking)); +  if (sizeof(ordinaryWords)) +  { +  words += ordinaryWords; +  push(do_query_or(db, ordinaryWords, ranking));    first = 0;    } -  foreach (q->phrases, array(string) ph) { +  foreach(ordinaryWordGlobs, string ordinaryWordGlob) +  { +  push(do_query_or(db, db->expand_word_glob(ordinaryWordGlob, max_globs), ranking)); +  if (!first) +  { +  Search.ResultSet r2 = pop(); +  Search.ResultSet r1 = pop(); +  push(r1 | r2); +  } +  first = 0; +  } +  foreach (q->phrases, array(string) ph) +  {    words += ph;    push(do_query_phrase(db, ph, ranking)); -  if (!first) { +  if(!first) +  {    Search.ResultSet r2 = pop();    Search.ResultSet r1 = pop();    push(r1 | r2);
226:    }    }    -  if (hasPlus && hasOrdinary) { +  if(hasPlus && hasOrdinary) +  {    Search.ResultSet r2 = pop();    Search.ResultSet r1 = pop();    // If a document contains must-have words AND ALSO may-have words,
234:    push(r1->add_ranking(r2));    }    -  if ((hasPlus || hasOrdinary) && hasMinus) { +  if((hasPlus || hasOrdinary) && hasMinus) +  {    int first = 1; -  if (sizeof(q->minusWords)) { +  if (sizeof(q->minusWords)) +  {    push(do_query_or(db, q->minusWords, ranking));    first = 0;    } -  foreach (q->minusPhrases, array(string) ph) { +  foreach(minusWordGlobs, string minusWordGlob) +  { +  push(do_query_or(db, db->expand_word_glob(minusWordGlob, max_globs), ranking)); +  if(!first) +  { +  Search.ResultSet r2 = pop(); +  Search.ResultSet r1 = pop(); +  push(r1 | r2); +  } +  first = 0; +  } +  foreach (q->minusPhrases, array(string) ph) +  {    push(do_query_phrase(db, ph, ranking)); -  if (!first) { +  if (!first) +  {    Search.ResultSet r2 = pop();    Search.ResultSet r1 = pop();    push(r1 | r2);
253:    Search.ResultSet r1 = pop();    push(r1 - r2);    } -  +     }    break;    default: