]> git.notmuchmail.org Git - notmuch/blobdiff - lib/regexp-fields.cc
lib: handle empty string in regexp field processors
[notmuch] / lib / regexp-fields.cc
index b41747502e1e6b8bbea31044e583e10b75a155a3..1651677cd8638b759a9f96838237a98aa2ef5af2 100644 (file)
@@ -62,11 +62,6 @@ RegexpPostingSource::init (const Xapian::Database &db)
     it_ = db_.valuestream_begin (slot_);
     end_ = db.valuestream_end (slot_);
     started_ = false;
-
-    /* make sure we start on a matching value */
-    while (!at_end() && regexec (&regexp_, (*it_).c_str (), 0, NULL, 0) != 0) {
-       ++it_;
-    }
 }
 
 Xapian::doccount
@@ -113,6 +108,27 @@ RegexpPostingSource::next (unused (double min_wt))
     }
 }
 
+void
+RegexpPostingSource::skip_to (Xapian::docid did, unused (double min_wt))
+{
+    started_ = true;
+    it_.skip_to (did);
+    for (; ! at_end (); ++it_) {
+       std::string value = *it_;
+       if (regexec (&regexp_, value.c_str (), 0, NULL, 0) == 0)
+           break;
+    }
+}
+
+bool
+RegexpPostingSource::check (Xapian::docid did, unused (double min_wt))
+{
+    started_ = true;
+    if (!it_.check (did) || at_end ())
+       return false;
+    return (regexec (&regexp_, (*it_).c_str (), 0, NULL, 0) == 0);
+}
+
 static inline Xapian::valueno _find_slot (std::string prefix)
 {
     if (prefix == "from")
@@ -132,6 +148,11 @@ RegexpFieldProcessor::RegexpFieldProcessor (std::string prefix, Xapian::QueryPar
 Xapian::Query
 RegexpFieldProcessor::operator() (const std::string & str)
 {
+    if (str.size () == 0)
+       return Xapian::Query(Xapian::Query::OP_AND_NOT,
+                            Xapian::Query::MatchAll,
+                            Xapian::Query (Xapian::Query::OP_WILDCARD, term_prefix));
+
     if (str.at (0) == '/') {
        if (str.at (str.size () - 1) == '/'){
            RegexpPostingSource *postings = new RegexpPostingSource (slot, str.substr(1,str.size () - 2));
@@ -142,8 +163,14 @@ RegexpFieldProcessor::operator() (const std::string & str)
     } else {
        /* TODO replace this with a nicer API level triggering of
         * phrase parsing, when possible */
-       std::string quoted='"' + str + '"';
-       return parser.parse_query (quoted, NOTMUCH_QUERY_PARSER_FLAGS, term_prefix);
+       std::string query_str;
+
+       if (str.find (' ') != std::string::npos)
+           query_str = '"' + str + '"';
+       else
+           query_str = str;
+
+       return parser.parse_query (query_str, NOTMUCH_QUERY_PARSER_FLAGS, term_prefix);
     }
 }
 #endif