summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Bremner <david@tethera.net>2021-08-24 08:17:34 -0700
committerDavid Bremner <david@tethera.net>2021-09-04 17:07:19 -0700
commitcc5992a30470222791c24849da04a3c0403ecce5 (patch)
treed8589f574fd9046d80384124d9c358b8232663cf /lib
parentafe85e65786df1df9abf261393b4b4e6e2e86009 (diff)
lib/parse-sexp: support infix subqueries
This is necessary so that programs can take infix syntax queries from a user and use the sexp query syntax to construct e.g. a refinement of that query.
Diffstat (limited to 'lib')
-rw-r--r--lib/parse-sexp.cc34
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc
index 9f6e0b77..e562e8f5 100644
--- a/lib/parse-sexp.cc
+++ b/lib/parse-sexp.cc
@@ -57,6 +57,8 @@ static _sexp_prefix_t prefixes[] =
SEXP_FLAG_FIELD | SEXP_FLAG_BOOLEAN | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX | SEXP_FLAG_EXPAND },
{ "id", Xapian::Query::OP_OR, Xapian::Query::MatchNothing,
SEXP_FLAG_FIELD | SEXP_FLAG_BOOLEAN | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX },
+ { "infix", Xapian::Query::OP_INVALID, Xapian::Query::MatchAll,
+ SEXP_FLAG_SINGLE },
{ "is", Xapian::Query::OP_AND, Xapian::Query::MatchAll,
SEXP_FLAG_FIELD | SEXP_FLAG_BOOLEAN | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX | SEXP_FLAG_EXPAND },
{ "matching", Xapian::Query::OP_AND, Xapian::Query::MatchAll,
@@ -242,6 +244,34 @@ _sexp_expand_query (notmuch_database_t *notmuch,
return status;
}
+static notmuch_status_t
+_sexp_parse_infix (notmuch_database_t *notmuch, const _sexp_prefix_t *parent,
+ const sexp_t *sx, Xapian::Query &output)
+{
+ if (parent) {
+ _notmuch_database_log (notmuch, "'infix' not supported inside '%s'\n", parent->name);
+ return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
+ }
+ try {
+ output = notmuch->query_parser->parse_query (sx->val, NOTMUCH_QUERY_PARSER_FLAGS);
+ } catch (const Xapian::QueryParserError &error) {
+ _notmuch_database_log (notmuch, "Syntax error in infix query: %s\n", sx->val);
+ return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
+ } catch (const Xapian::Error &error) {
+ if (! notmuch->exception_reported) {
+ _notmuch_database_log (notmuch,
+ "A Xapian exception occurred parsing query: %s\n",
+ error.get_msg ().c_str ());
+ _notmuch_database_log_append (notmuch,
+ "Query string was: %s\n",
+ sx->val);
+ notmuch->exception_reported = true;
+ return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+ }
+ }
+ return NOTMUCH_STATUS_SUCCESS;
+}
+
/* Here we expect the s-expression to be a proper list, with first
* element defining and operation, or as a special case the empty
* list */
@@ -311,6 +341,10 @@ _sexp_to_xapian_query (notmuch_database_t *notmuch, const _sexp_prefix_t *parent
return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
}
+ if (strcmp (prefix->name, "infix") == 0) {
+ return _sexp_parse_infix (notmuch, parent, sx->list->next, output);
+ }
+
if (prefix->xapian_op == Xapian::Query::OP_WILDCARD)
return _sexp_parse_wildcard (notmuch, parent, sx->list->next->val, output);