From eab365c742f86b52729ec2a5acaba1a798f94661 Mon Sep 17 00:00:00 2001 From: David Bremner Date: Wed, 15 Feb 2017 08:58:28 -0400 Subject: [PATCH] lib: Add regexp searching for mid: prefix The bulk of the change is passing in the field options to the regexp field processor, so that we can properly handle the fallback (non-regexp case). --- lib/database.cc | 6 ++++-- lib/regexp-fields.cc | 36 +++++++++++++++++++++++++----------- lib/regexp-fields.h | 4 +++- test/T650-regexp-query.sh | 16 ++++++++++++++++ 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/lib/database.cc b/lib/database.cc index 5bc131a3..49b3849c 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -262,7 +262,8 @@ prefix_t prefix_table[] = { { "tag", "K", NOTMUCH_FIELD_EXTERNAL }, { "is", "K", NOTMUCH_FIELD_EXTERNAL }, { "id", "Q", NOTMUCH_FIELD_EXTERNAL }, - { "mid", "Q", NOTMUCH_FIELD_EXTERNAL }, + { "mid", "Q", NOTMUCH_FIELD_EXTERNAL | + NOTMUCH_FIELD_PROCESSOR }, { "path", "P", NOTMUCH_FIELD_EXTERNAL }, { "property", "XPROPERTY", NOTMUCH_FIELD_EXTERNAL }, /* @@ -313,7 +314,8 @@ _setup_query_field (const prefix_t *prefix, notmuch_database_t *notmuch) else if (STRNCMP_LITERAL(prefix->name, "query") == 0) fp = (new QueryFieldProcessor (*notmuch->query_parser, notmuch))->release (); else - fp = (new RegexpFieldProcessor (prefix->name, *notmuch->query_parser, notmuch))->release (); + fp = (new RegexpFieldProcessor (prefix->name, prefix->flags, + *notmuch->query_parser, notmuch))->release (); /* we treat all field-processor fields as boolean in order to get the raw input */ notmuch->query_parser->add_boolean_prefix (prefix->name, fp); diff --git a/lib/regexp-fields.cc b/lib/regexp-fields.cc index 1651677c..7ae55e70 100644 --- a/lib/regexp-fields.cc +++ b/lib/regexp-fields.cc @@ -135,13 +135,21 @@ static inline Xapian::valueno _find_slot (std::string prefix) return NOTMUCH_VALUE_FROM; else if (prefix == "subject") return NOTMUCH_VALUE_SUBJECT; + else if (prefix == "mid") + return NOTMUCH_VALUE_MESSAGE_ID; else throw Xapian::QueryParserError ("unsupported regexp field '" + prefix + "'"); } -RegexpFieldProcessor::RegexpFieldProcessor (std::string prefix, Xapian::QueryParser &parser_, notmuch_database_t *notmuch_) - : slot (_find_slot (prefix)), term_prefix (_find_prefix (prefix.c_str ())), - parser (parser_), notmuch (notmuch_) +RegexpFieldProcessor::RegexpFieldProcessor (std::string prefix, + notmuch_field_flag_t options_, + Xapian::QueryParser &parser_, + notmuch_database_t *notmuch_) + : slot (_find_slot (prefix)), + term_prefix (_find_prefix (prefix.c_str ())), + options (options_), + parser (parser_), + notmuch (notmuch_) { }; @@ -161,16 +169,22 @@ RegexpFieldProcessor::operator() (const std::string & str) throw Xapian::QueryParserError ("unmatched regex delimiter in '" + str + "'"); } } else { - /* TODO replace this with a nicer API level triggering of - * phrase parsing, when possible */ - std::string query_str; + if (options & NOTMUCH_FIELD_PROBABILISTIC) { + /* TODO replace this with a nicer API level triggering of + * phrase parsing, when possible */ + std::string query_str; - if (str.find (' ') != std::string::npos) - query_str = '"' + str + '"'; - else - query_str = 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); + return parser.parse_query (query_str, NOTMUCH_QUERY_PARSER_FLAGS, term_prefix); + } else { + /* Boolean prefix */ + std::string term = term_prefix + str; + return Xapian::Query (term); + } } } #endif diff --git a/lib/regexp-fields.h b/lib/regexp-fields.h index a4ba7ad8..d5f93445 100644 --- a/lib/regexp-fields.h +++ b/lib/regexp-fields.h @@ -65,11 +65,13 @@ class RegexpFieldProcessor : public Xapian::FieldProcessor { protected: Xapian::valueno slot; std::string term_prefix; + notmuch_field_flag_t options; Xapian::QueryParser &parser; notmuch_database_t *notmuch; public: - RegexpFieldProcessor (std::string prefix, Xapian::QueryParser &parser_, notmuch_database_t *notmuch_); + RegexpFieldProcessor (std::string prefix, notmuch_field_flag_t options, + Xapian::QueryParser &parser_, notmuch_database_t *notmuch_); ~RegexpFieldProcessor () { }; diff --git a/test/T650-regexp-query.sh b/test/T650-regexp-query.sh index 9599c104..27fc9ab9 100755 --- a/test/T650-regexp-query.sh +++ b/test/T650-regexp-query.sh @@ -104,4 +104,20 @@ Query string was: from:/unbalanced[/ EOF test_expect_equal_file EXPECTED OUTPUT +test_begin_subtest "empty mid search" +notmuch search --output=messages mid:yoom > OUTPUT +cp /dev/null EXPECTED +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "non-empty mid regex search" +notmuch search --output=messages mid:/yoom/ > OUTPUT +test_expect_equal_file cworth.msg-ids OUTPUT + +test_begin_subtest "combine regexp mid and subject" +notmuch search subject:/-C/ and mid:/y..m/ | notmuch_search_sanitize > OUTPUT +cat < EXPECTED +thread:XXX 2009-11-18 [1/2] Carl Worth| Jan Janak; [notmuch] [PATCH] Older versions of install do not support -C. (inbox unread) +EOF +test_expect_equal_file EXPECTED OUTPUT + test_done