Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 88056429E2F for ; Sun, 16 Jan 2011 00:11:39 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: 0 X-Spam-Level: X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cBjJsomRgZk7 for ; Sun, 16 Jan 2011 00:11:38 -0800 (PST) Received: from dmz-mailsec-scanner-2.mit.edu (DMZ-MAILSEC-SCANNER-2.MIT.EDU [18.9.25.13]) by olra.theworths.org (Postfix) with ESMTP id 823F342D29B for ; Sun, 16 Jan 2011 00:11:25 -0800 (PST) X-AuditID: 1209190d-b7cacae000000a14-a8-4d32a82df995 Received: from mailhub-auth-4.mit.edu ( [18.7.62.39]) by dmz-mailsec-scanner-2.mit.edu (Symantec Brightmail Gateway) with SMTP id 5A.C7.02580.D28A23D4; Sun, 16 Jan 2011 03:11:25 -0500 (EST) Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103]) by mailhub-auth-4.mit.edu (8.13.8/8.9.2) with ESMTP id p0G8BPcR024334; Sun, 16 Jan 2011 03:11:25 -0500 Received: from drake.mit.edu (a074.catapulsion.net [70.36.81.74]) (authenticated bits=0) (User authenticated as amdragon@ATHENA.MIT.EDU) by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id p0G8BNLT010530 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT); Sun, 16 Jan 2011 03:11:24 -0500 (EST) Received: from amthrax by drake.mit.edu with local (Exim 4.72) (envelope-from ) id 1PeNhr-0002Xg-0w; Sun, 16 Jan 2011 03:11:23 -0500 From: Austin Clements To: notmuch@notmuchmail.org Subject: [PATCH 7/8] Implement value range queries. Date: Sun, 16 Jan 2011 03:10:57 -0500 Message-Id: <1295165458-9573-8-git-send-email-amdragon@mit.edu> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1295165458-9573-1-git-send-email-amdragon@mit.edu> References: <1295165458-9573-1-git-send-email-amdragon@mit.edu> X-Brightmail-Tracker: AAAAAA== Cc: amdragon@mit.edu X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 16 Jan 2011 08:11:40 -0000 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