[PATCH 4/8] Replace Xapian query parser with custom query parser.

Austin Clements amdragon at MIT.EDU
Sun Jan 16 00:10:54 PST 2011


Note that the type:mail filter is implemented as a transform pass, so
it no longer has to be done everywhere queries are parsed.
Furthermore, this filter now depends on the prefixing logic in the
query parser instead of implementing this itself.  Likewise, we don't
need to special-case the queries "" and "*" in multiple places.
---
 lib/database-private.h |    3 +-
 lib/database.cc        |   33 ++++++++++++++-----------
 lib/query.cc           |   62 ++++++++++++++++++-----------------------------
 3 files changed, 44 insertions(+), 54 deletions(-)

diff --git a/lib/database-private.h b/lib/database-private.h
index 5d2fa02..a6eea87 100644
--- a/lib/database-private.h
+++ b/lib/database-private.h
@@ -48,9 +48,8 @@ struct _notmuch_database {
     unsigned int last_doc_id;
     uint64_t last_thread_id;
 
-    Xapian::QueryParser *query_parser;
     Xapian::TermGenerator *term_gen;
-    Xapian::ValueRangeProcessor *value_range_processor;
+    _notmuch_qparser_t *query_parser;
 };
 
 /* Return the list of terms from the given iterator matching a prefix.
diff --git a/lib/database.cc b/lib/database.cc
index f8245ab..a3df0ae 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -571,6 +571,17 @@ _notmuch_database_ensure_writable (notmuch_database_t *notmuch)
     return NOTMUCH_STATUS_SUCCESS;
 }
 
+static _notmuch_token_t *
+transform_type_mail (_notmuch_token_t *root, unused (void *opaque))
+{
+    _notmuch_token_t *mail_ast =
+	_notmuch_token_create_term (root, TOK_LIT, "mail");
+    mail_ast->prefix = talloc_strdup (root, _find_prefix ("type"));
+    if (!root)
+	return mail_ast;
+    return _notmuch_token_create_op (root, TOK_AND, mail_ast, root);
+}
+
 notmuch_database_t *
 notmuch_database_open (const char *path,
 		       notmuch_database_mode_t mode)
@@ -661,27 +672,24 @@ notmuch_database_open (const char *path,
 		INTERNAL_ERROR ("Malformed database last_thread_id: %s", str);
 	}
 
-	notmuch->query_parser = new Xapian::QueryParser;
 	notmuch->term_gen = new Xapian::TermGenerator;
 	notmuch->term_gen->set_stemmer (Xapian::Stem ("english"));
-	notmuch->value_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP);
-
-	notmuch->query_parser->set_default_op (Xapian::Query::OP_AND);
-	notmuch->query_parser->set_database (*notmuch->xapian_db);
-	notmuch->query_parser->set_stemmer (Xapian::Stem ("english"));
-	notmuch->query_parser->set_stemming_strategy (Xapian::QueryParser::STEM_SOME);
-	notmuch->query_parser->add_valuerangeprocessor (notmuch->value_range_processor);
+	notmuch->query_parser = _notmuch_qparser_create (notmuch, notmuch);
 
 	for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_EXTERNAL); i++) {
 	    prefix_t *prefix = &BOOLEAN_PREFIX_EXTERNAL[i];
-	    notmuch->query_parser->add_boolean_prefix (prefix->name,
-						       prefix->prefix);
+	    _notmuch_qparser_add_db_prefix (notmuch->query_parser, prefix->name,
+					    prefix->prefix, TRUE);
 	}
 
 	for (i = 0; i < ARRAY_SIZE (PROBABILISTIC_PREFIX); i++) {
 	    prefix_t *prefix = &PROBABILISTIC_PREFIX[i];
-	    notmuch->query_parser->add_prefix (prefix->name, prefix->prefix);
+	    _notmuch_qparser_add_db_prefix (notmuch->query_parser, prefix->name,
+					    prefix->prefix, FALSE);
 	}
+
+	_notmuch_qparser_add_transform (notmuch->query_parser,
+					transform_type_mail, NULL);
     } catch (const Xapian::Error &error) {
 	fprintf (stderr, "A Xapian exception occurred opening database: %s\n",
 		 error.get_msg().c_str());
@@ -711,9 +719,6 @@ notmuch_database_close (notmuch_database_t *notmuch)
     }
 
     delete notmuch->term_gen;
-    delete notmuch->query_parser;
-    delete notmuch->xapian_db;
-    delete notmuch->value_range_processor;
     talloc_free (notmuch);
 }
 
diff --git a/lib/query.cc b/lib/query.cc
index c7ae4ee..993f498 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -131,27 +131,21 @@ notmuch_query_search_messages (notmuch_query_t *query)
 	talloc_set_destructor (messages, _notmuch_messages_destructor);
 
 	Xapian::Enquire enquire (*notmuch->xapian_db);
-	Xapian::Query mail_query (talloc_asprintf (query, "%s%s",
-						   _find_prefix ("type"),
-						   "mail"));
-	Xapian::Query string_query, final_query;
+	_notmuch_token_t *ast;
+	Xapian::Query final_query;
 	Xapian::MSet mset;
-	unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
-			      Xapian::QueryParser::FLAG_PHRASE |
-			      Xapian::QueryParser::FLAG_LOVEHATE |
-			      Xapian::QueryParser::FLAG_BOOLEAN_ANY_CASE |
-			      Xapian::QueryParser::FLAG_WILDCARD |
-			      Xapian::QueryParser::FLAG_PURE_NOT);
+	char *error;
 
-	if (strcmp (query_string, "") == 0 ||
-	    strcmp (query_string, "*") == 0)
-	{
-	    final_query = mail_query;
-	} else {
-	    string_query = notmuch->query_parser->
-		parse_query (query_string, flags);
-	    final_query = Xapian::Query (Xapian::Query::OP_AND,
-					 mail_query, string_query);
+	ast = _notmuch_qparser_parse (query, notmuch->query_parser,
+				      query_string);
+	ast = _notmuch_qparser_transform (notmuch->query_parser, ast);
+	final_query = _notmuch_qparser_generate (query, notmuch->query_parser,
+						 ast, &error);
+	if (error) {
+	    fprintf (stderr, "Query error: %s\n", error);
+	    notmuch->exception_reported = TRUE;
+	    talloc_free (messages);
+	    return NULL;
 	}
 
 	enquire.set_weighting_scheme (Xapian::BoolWeight());
@@ -412,27 +406,19 @@ notmuch_query_count_messages (notmuch_query_t *query)
 
     try {
 	Xapian::Enquire enquire (*notmuch->xapian_db);
-	Xapian::Query mail_query (talloc_asprintf (query, "%s%s",
-						   _find_prefix ("type"),
-						   "mail"));
-	Xapian::Query string_query, final_query;
+	_notmuch_token_t *ast;
+	Xapian::Query final_query;
 	Xapian::MSet mset;
-	unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
-			      Xapian::QueryParser::FLAG_PHRASE |
-			      Xapian::QueryParser::FLAG_LOVEHATE |
-			      Xapian::QueryParser::FLAG_BOOLEAN_ANY_CASE |
-			      Xapian::QueryParser::FLAG_WILDCARD |
-			      Xapian::QueryParser::FLAG_PURE_NOT);
+	char *error;
 
-	if (strcmp (query_string, "") == 0 ||
-	    strcmp (query_string, "*") == 0)
-	{
-	    final_query = mail_query;
-	} else {
-	    string_query = notmuch->query_parser->
-		parse_query (query_string, flags);
-	    final_query = Xapian::Query (Xapian::Query::OP_AND,
-					 mail_query, string_query);
+	ast = _notmuch_qparser_parse (query, notmuch->query_parser,
+				      query_string);
+	ast = _notmuch_qparser_transform (notmuch->query_parser, ast);
+	final_query = _notmuch_qparser_generate (query, notmuch->query_parser,
+						 ast, &error);
+	if (error) {
+	    fprintf (stderr, "Query error: %s\n", error);
+	    return count;
 	}
 
 	enquire.set_weighting_scheme(Xapian::BoolWeight());
-- 
1.7.2.3



More information about the notmuch mailing list