lib/parse-sexp: handle unprefixed terms.

This is equivalent to adding the same field name "" for multiple
prefixes in the Xapian query parser, but we have to explicitely
construct the resulting query.
This commit is contained in:
David Bremner 2021-08-24 08:17:26 -07:00
parent 0ca4ad2670
commit bafc307190
2 changed files with 59 additions and 8 deletions

View file

@ -164,6 +164,22 @@ _sexp_parse_wildcard (notmuch_database_t *notmuch,
return NOTMUCH_STATUS_SUCCESS; return NOTMUCH_STATUS_SUCCESS;
} }
static notmuch_status_t
_sexp_parse_one_term (notmuch_database_t *notmuch, std::string term_prefix, const sexp_t *sx,
Xapian::Query &output)
{
Xapian::Stem stem = *(notmuch->stemmer);
if (sx->aty == SEXP_BASIC && unicode_word_utf8 (sx->val)) {
std::string term = Xapian::Unicode::tolower (sx->val);
output = Xapian::Query ("Z" + term_prefix + stem (term));
return NOTMUCH_STATUS_SUCCESS;
} else {
return _sexp_parse_phrase (term_prefix, sx->val, output);
}
}
/* Here we expect the s-expression to be a proper list, with first /* Here we expect the s-expression to be a proper list, with first
* element defining and operation, or as a special case the empty * element defining and operation, or as a special case the empty
* list */ * list */
@ -185,11 +201,23 @@ _sexp_to_xapian_query (notmuch_database_t *notmuch, const _sexp_prefix_t *parent
output = Xapian::Query (term_prefix + sx->val); output = Xapian::Query (term_prefix + sx->val);
return NOTMUCH_STATUS_SUCCESS; return NOTMUCH_STATUS_SUCCESS;
} }
if (sx->aty == SEXP_BASIC && unicode_word_utf8 (sx->val)) { if (parent) {
output = Xapian::Query ("Z" + term_prefix + stem (term)); return _sexp_parse_one_term (notmuch, term_prefix, sx, output);
return NOTMUCH_STATUS_SUCCESS;
} else { } else {
return _sexp_parse_phrase (term_prefix, sx->val, output); Xapian::Query accumulator;
for (_sexp_prefix_t *prefix = prefixes; prefix->name; prefix++) {
if (prefix->flags & SEXP_FLAG_FIELD) {
notmuch_status_t status;
Xapian::Query subquery;
term_prefix = _find_prefix (prefix->name);
status = _sexp_parse_one_term (notmuch, term_prefix, sx, subquery);
if (status)
return status;
accumulator = Xapian::Query (Xapian::Query::OP_OR, accumulator, subquery);
}
}
output = accumulator;
return NOTMUCH_STATUS_SUCCESS;
} }
} }

View file

@ -122,6 +122,29 @@ add_message '[subject]="utf8-message-body-subject"' '[date]="Sat, 01 Jan 2000 12
output=$(notmuch search --query=sexp '(body bödý)' | notmuch_search_sanitize) output=$(notmuch search --query=sexp '(body bödý)' | notmuch_search_sanitize)
test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread)" test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread)"
add_message "[body]=thebody-1" "[subject]=kryptonite-1"
add_message "[body]=nothing-to-see-here-1" "[subject]=thebody-1"
test_begin_subtest 'search without body: prefix'
notmuch search thebody > EXPECTED
notmuch search --query=sexp '(and thebody)' > OUTPUT
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest 'negated body: prefix'
notmuch search thebody and not body:thebody > EXPECTED
notmuch search --query=sexp '(and (not (body thebody)) thebody)' > OUTPUT
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest 'search unprefixed for prefixed term'
notmuch search kryptonite > EXPECTED
notmuch search --query=sexp '(and kryptonite)' > OUTPUT
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest 'search with body: prefix for term only in subject'
notmuch search body:kryptonite > EXPECTED
notmuch search --query=sexp '(body kryptonite)' > OUTPUT
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "Search by 'from'" test_begin_subtest "Search by 'from'"
add_message '[subject]="search by from"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [from]=searchbyfrom add_message '[subject]="search by from"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [from]=searchbyfrom
output=$(notmuch search --query=sexp '(from searchbyfrom)' | notmuch_search_sanitize) output=$(notmuch search --query=sexp '(from searchbyfrom)' | notmuch_search_sanitize)
@ -287,11 +310,11 @@ output=$(notmuch search --query=sexp '(attachment (starts-with not))' | notmuch_
test_expect_equal "$output" 'thread:XXX 2009-11-18 [2/2] Lars Kellogg-Stedman; [notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread)' test_expect_equal "$output" 'thread:XXX 2009-11-18 [2/2] Lars Kellogg-Stedman; [notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread)'
test_begin_subtest "starts-with, folder" test_begin_subtest "starts-with, folder"
notmuch search --output=files --query=sexp '(folder (starts-with bad))' | notmuch_dir_sanitize > OUTPUT notmuch search --output=files --query=sexp '(folder (starts-with bad))' | notmuch_dir_sanitize | sed 's/[0-9]*$/XXX/' > OUTPUT
cat <<EOF > EXPECTED cat <<EOF > EXPECTED
MAIL_DIR/bad/msg-010 MAIL_DIR/bad/msg-XXX
MAIL_DIR/bad/news/msg-012 MAIL_DIR/bad/news/msg-XXX
MAIL_DIR/duplicate/bad/news/msg-012 MAIL_DIR/duplicate/bad/news/msg-XXX
EOF EOF
test_expect_equal_file EXPECTED OUTPUT test_expect_equal_file EXPECTED OUTPUT