Ticket #245: qp-allstop.patch

File qp-allstop.patch, 3.0 KB (added by Olly Betts, 16 years ago)

Simple approach to fixing this

  • queryparser/queryparser.lemony

     
    174174    QueryParser::Internal * qpi;
    175175
    176176  public:
     177    const Stopper * stopper;
    177178    Query query;
    178179    const char * error;
    179180    unsigned flags;
    180181
    181182    State(QueryParser::Internal * qpi_, unsigned flags_)
    182         : qpi(qpi_), error(NULL), flags(flags_) { }
     183        : qpi(qpi_), stopper(qpi->stopper), error(NULL), flags(flags_) { }
    183184
    184185    string stem_term(const string &term) {
    185186        return qpi->stemmer(term);
     
    220221    Query::op default_op() const { return qpi->default_op; }
    221222
    222223    bool is_stopword(const Term *term) const {
    223         return qpi->stopper && (*qpi->stopper)(term->name);
     224        return stopper && (*stopper)(term->name);
    224225    }
    225226
    226227    Database get_database() const {
     
    547548    bool value_ranges;
    548549    value_ranges = !valrangeprocs.empty() && (qs.find("..") != string::npos);
    549550
     551    State state(this, flags);
     552
     553reparse_without_stopwords:
    550554    termpos term_pos = 1;
    551555    Utf8Iterator it(qs), end;
    552556
    553     State state(this, flags);
    554 
    555557    // To successfully apply more than one spelling correction to a query
    556558    // string, we must keep track of the offset due to previous corrections.
    557559    int correction_offset = 0;
     
    10291031    if (mode == IN_QUOTES || mode == IN_PREFIXED_QUOTES)
    10301032        Parse(pParser, QUOTE, NULL, &state);
    10311033    Parse(pParser, 0, NULL, &state);
     1034
     1035    if (!state.error && state.query.empty() && state.stopper &&
     1036        !stoplist.empty()) {
     1037        // All terms were stopwords so reparse with stopwords disabled.
     1038        stoplist.clear();
     1039        unstem.clear();
     1040        state.stopper = NULL;
     1041        goto reparse_without_stopwords;
     1042    }
    10321043    ParseFree(pParser);
    10331044
    10341045    errmsg = state.error;
     
    14471458        }
    14481459        *E = Query(Query::OP_AND_NOT, *E, *P->hate);
    14491460    }
    1450     // FIXME what if E && E->empty() (all terms are stopwords)?
    14511461    delete P;
    14521462}
    14531463
  • tests/queryparsertest.cc

     
    10071007    // parse.
    10081008    { "test AND the AND queryparser", "(test:(pos=1) AND the:(pos=2) AND queryparser:(pos=3))" },
    10091009    // 0.9.6 and earlier ignored a stopword even if it was the only term.
    1010     // We don't ignore it in this case, which is probably better.  But
    1011     // an all-stopword query with multiple terms doesn't work, which
    1012     // prevents 'to be or not to be' for being searchable unless made
    1013     // into a phrase query.
     1010    // More recent versions don't ever treat a single term as a stopword.
    10141011    { "the", "the:(pos=1)" },
     1012    // 1.0.5 and earlier ignored an all-stopword query with multiple terms,
     1013    // which prevents 'to be or not to be' for being searchable unless made
     1014    // into a phrase query by the user.
     1015    { "an the a", "(an:(pos=1) AND the:(pos=2) AND a:(pos=3))" },
     1016    // FIXME: this still doesn't work...
     1017    { "the AND a an", "" },
    10151018    { NULL, NULL }
    10161019};
    10171020