[PATCH 7/8] Implement value range queries.
Austin Clements
amdragon at MIT.EDU
Sun Jan 16 00:10:57 PST 2011
Unlike in Xapian, there's no specific syntax that generates value
ranges. Instead, it's up query transforms to generate them.
---
lib/notmuch-private.h | 8 ++++++++
lib/qparser.cc | 20 +++++++++++++++++---
2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 5fc54de..9c16f56 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -548,6 +548,8 @@ enum _notmuch_token_type {
* with no phrase splitting or whitespace removal. The lexer
* only generates TOK_TERMS; the parser creates TOK_LIT. */
TOK_LIT,
+ /* A value range operand. */
+ TOK_RANGE,
/* An error token. An error token anywhere in the parse tree will
* be propagated up by the generator and returned to the caller.
* The error message should be in the text. */
@@ -577,6 +579,12 @@ typedef struct _notmuch_token {
* match any terms prefixed with text. */
notmuch_bool_t wildcard;
+ /* For TOK_RANGE, the value number to filter on, and the
+ * (inclusive) range to match lexicographically. Either endpoint
+ * may be NULL, indicating an open-ended range. */
+ unsigned valueno;
+ const char *rangeBegin, *rangeEnd;
+
/* Link in the lexer token list. */
struct _notmuch_token *next;
diff --git a/lib/qparser.cc b/lib/qparser.cc
index 0ff240c..2c63062 100644
--- a/lib/qparser.cc
+++ b/lib/qparser.cc
@@ -43,7 +43,6 @@
* Still missing from this implementation:
* * Stemming - The stemming should probably be marked on TOK_TERMS
* tokens. Ideally, we can just pass this to the term generator.
- * * Value ranges in the IR
*/
/* XXX notmuch currently registers "tag" as an exclusive boolean
@@ -100,13 +99,13 @@ static const char *token_types[] = {
"LOVE", "HATE", "BRA", "KET",
"AND", "OR", "XOR", "ADJ", "NEAR",
"NOT", "FILTER", "PREFIX",
- "TERMS", "LIT", "ERROR", "END"
+ "TERMS", "LIT", "ERROR", "RANGE", "END"
};
/* The distinguished end token. This simplifies the parser since it
* never has to worry about dereferencing next. */
static _notmuch_token_t tok_end = {TOK_END, NULL, -1, FALSE, NULL, FALSE,
- &tok_end, NULL, NULL};
+ 0, NULL, NULL, &tok_end, NULL, NULL};
_notmuch_token_t *
_notmuch_token_create_op (const void *ctx, enum _notmuch_token_type type,
@@ -145,6 +144,9 @@ _notmuch_token_show (const void *ctx, _notmuch_token_t *tok)
else if (tok->type == TOK_LIT)
return talloc_asprintf (ctx, "'%s'%s", tok->text,
tok->wildcard ? "*" : "");
+ else if (tok->type == TOK_RANGE)
+ return talloc_asprintf (ctx, "RANGE/%d:%s..%s",
+ tok->valueno, tok->rangeBegin, tok->rangeEnd);
else if (tok->type == TOK_ERROR)
return talloc_asprintf (ctx, "ERROR/\"%s\"", tok->text);
@@ -536,6 +538,7 @@ parse_prob (struct _notmuch_parse_state *s, int prec, _notmuch_token_t **tok)
break;
case TOK_FILTER:
+ case TOK_RANGE:
case TOK_ERROR:
INTERNAL_ERROR ("Unexpected token %s",
_notmuch_token_show (s->ctx, *tok));
@@ -902,6 +905,17 @@ generate (struct _notmuch_generate_state *s, _notmuch_token_t *root)
return generate_wildcard (s, term);
return Query (term);
+ case TOK_RANGE:
+ if (root->rangeBegin && root->rangeEnd)
+ return Query (Query::OP_VALUE_RANGE, root->valueno,
+ root->rangeBegin, root->rangeEnd);
+ else if (root->rangeBegin)
+ return Query (Query::OP_VALUE_GE, root->valueno, root->rangeBegin);
+ else if (root->rangeEnd)
+ return Query (Query::OP_VALUE_LE, root->valueno, root->rangeEnd);
+ else
+ INTERNAL_ERROR ("TOK_RANGE must have an endpoint");
+
case TOK_ERROR:
if (!s->error)
s->error = talloc_strdup (s->ctx, root->text);
--
1.7.2.3
More information about the notmuch
mailing list