--- lib/parse-sexp.cc | 35 ++++++++++++++++++++++++++++++++--- test/T081-sexpr-search.sh | 6 ++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc index 9cadbc13..1faa9023 100644 --- a/lib/parse-sexp.cc +++ b/lib/parse-sexp.cc @@ -34,6 +34,8 @@ typedef enum { SEXP_FLAG_ORPHAN = 1 << 8, SEXP_FLAG_RANGE = 1 << 9, SEXP_FLAG_PATHNAME = 1 << 10, + SEXP_FLAG_COUNT = 1 << 11, + SEXP_FLAG_MODIFIER = 1 << 12, } _sexp_flag_t; /* @@ -70,6 +72,8 @@ static _sexp_prefix_t prefixes[] = SEXP_FLAG_FIELD }, { "date", Xapian::Query::OP_INVALID, Xapian::Query::MatchAll, SEXP_FLAG_RANGE }, + { "count", Xapian::Query::OP_INVALID, Xapian::Query::MatchAll, + SEXP_FLAG_RANGE | SEXP_FLAG_MODIFIER }, { "from", Xapian::Query::OP_AND, Xapian::Query::MatchAll, SEXP_FLAG_FIELD | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX | SEXP_FLAG_EXPAND }, { "folder", Xapian::Query::OP_OR, Xapian::Query::MatchNothing, @@ -113,7 +117,8 @@ static _sexp_prefix_t prefixes[] = { "tag", Xapian::Query::OP_AND, Xapian::Query::MatchAll, SEXP_FLAG_FIELD | SEXP_FLAG_BOOLEAN | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX | SEXP_FLAG_EXPAND }, { "thread", Xapian::Query::OP_OR, Xapian::Query::MatchNothing, - SEXP_FLAG_FIELD | SEXP_FLAG_BOOLEAN | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX | SEXP_FLAG_EXPAND }, + SEXP_FLAG_FIELD | SEXP_FLAG_BOOLEAN | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX | + SEXP_FLAG_EXPAND | SEXP_FLAG_COUNT }, { "to", Xapian::Query::OP_AND, Xapian::Query::MatchAll, SEXP_FLAG_FIELD | SEXP_FLAG_WILDCARD | SEXP_FLAG_EXPAND }, { } @@ -513,6 +518,7 @@ _sexp_expand_param (notmuch_database_t *notmuch, const _sexp_prefix_t *parent, static notmuch_status_t _sexp_parse_range (notmuch_database_t *notmuch, const _sexp_prefix_t *prefix, + const _sexp_prefix_t *parent, const sexp_t *sx, Xapian::Query &output) { const char *from, *to; @@ -552,6 +558,27 @@ _sexp_parse_range (notmuch_database_t *notmuch, const _sexp_prefix_t *prefix, to = ""; } + if (strcmp (prefix->name, "count") == 0) { + notmuch_status_t status; + if (! parent) { + _notmuch_database_log (notmuch, "illegal '%s' outside field\n", + prefix->name); + return NOTMUCH_STATUS_BAD_QUERY_SYNTAX; + } + if (! (parent->flags & SEXP_FLAG_COUNT)) { + _notmuch_database_log (notmuch, "'%s' not supported in field '%s'\n", + prefix->name, parent->name); + return NOTMUCH_STATUS_BAD_QUERY_SYNTAX; + } + + status = _notmuch_count_strings_to_query (notmuch, parent->name, from, to, output, msg); + if (status) { + if (! msg.empty ()) + _notmuch_database_log (notmuch, "%s\n", msg.c_str ()); + } + return status; + } + if (strcmp (prefix->name, "date") == 0) { notmuch_status_t status; status = _notmuch_date_strings_to_query (NOTMUCH_VALUE_TIMESTAMP, from, to, output, msg); @@ -654,7 +681,9 @@ _sexp_to_xapian_query (notmuch_database_t *notmuch, const _sexp_prefix_t *parent for (_sexp_prefix_t *prefix = prefixes; prefix && prefix->name; prefix++) { if (strcmp (prefix->name, sx->list->val) == 0) { - if (prefix->flags & (SEXP_FLAG_FIELD | SEXP_FLAG_RANGE)) { + if ((prefix->flags & (SEXP_FLAG_FIELD)) || + ((prefix->flags & SEXP_FLAG_RANGE) && + ! (prefix->flags & SEXP_FLAG_MODIFIER))) { if (parent) { _notmuch_database_log (notmuch, "nested field: '%s' inside '%s'\n", prefix->name, parent->name); @@ -677,7 +706,7 @@ _sexp_to_xapian_query (notmuch_database_t *notmuch, const _sexp_prefix_t *parent } if (prefix->flags & SEXP_FLAG_RANGE) - return _sexp_parse_range (notmuch, prefix, sx->list->next, output); + return _sexp_parse_range (notmuch, prefix, parent, sx->list->next, output); if (strcmp (prefix->name, "infix") == 0) { return _sexp_parse_infix (notmuch, sx->list->next, output); diff --git a/test/T081-sexpr-search.sh b/test/T081-sexpr-search.sh index 0c7db9c2..2013fa5c 100755 --- a/test/T081-sexpr-search.sh +++ b/test/T081-sexpr-search.sh @@ -1318,5 +1318,11 @@ notmuch search subject:notmuch or List:notmuch | notmuch_search_sanitize > EXPEC notmuch search --query=sexp '(About notmuch)' | notmuch_search_sanitize > OUTPUT test_expect_equal_file EXPECTED OUTPUT +test_begin_subtest "threads with one message" +notmuch search --query=sexp '(and (from gusarov) (thread (count 1)))' | notmuch_search_sanitize > OUTPUT +cat <<EOF >EXPECTED +thread:XXX 2009-11-17 [1/1] Mikhail Gusarov; [notmuch] [PATCH] Handle rename of message file (inbox unread) +EOF +test_expect_equal_file EXPECTED OUTPUT test_done -- 2.39.1 _______________________________________________ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-leave@notmuchmail.org