Re: How does notmuch track mails?
[notmuch-archives.git] / 3c / 5accc817d1efa0546789f8c73cd3d485a4d5ff
1 Return-Path: <amthrax@awakening.csail.mit.edu>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5         by olra.theworths.org (Postfix) with ESMTP id D644341732C\r
6         for <notmuch@notmuchmail.org>; Wed, 22 Dec 2010 22:00:46 -0800 (PST)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: 0\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]\r
12         autolearn=disabled\r
13 Received: from olra.theworths.org ([127.0.0.1])\r
14         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
15         with ESMTP id eX9eLqJQTrK4 for <notmuch@notmuchmail.org>;\r
16         Wed, 22 Dec 2010 22:00:41 -0800 (PST)\r
17 Received: from dmz-mailsec-scanner-8.mit.edu (DMZ-MAILSEC-SCANNER-8.MIT.EDU\r
18         [18.7.68.37])\r
19         by olra.theworths.org (Postfix) with ESMTP id 53BF2431FB6\r
20         for <notmuch@notmuchmail.org>; Wed, 22 Dec 2010 22:00:39 -0800 (PST)\r
21 X-AuditID: 12074425-b7c98ae000000a04-9b-4d12e586e4d1\r
22 Received: from mailhub-auth-1.mit.edu ( [18.9.21.35])\r
23         by dmz-mailsec-scanner-8.mit.edu (Symantec Brightmail Gateway) with\r
24         SMTP id D9.05.02564.685E21D4; Thu, 23 Dec 2010 01:00:38 -0500 (EST)\r
25 Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103])\r
26         by mailhub-auth-1.mit.edu (8.13.8/8.9.2) with ESMTP id oBN60bMt020117; \r
27         Thu, 23 Dec 2010 01:00:37 -0500\r
28 Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91])\r
29         (authenticated bits=0)\r
30         (User authenticated as amdragon@ATHENA.MIT.EDU)\r
31         by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id oBN60Z1i004772\r
32         (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT);\r
33         Thu, 23 Dec 2010 01:00:37 -0500 (EST)\r
34 Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.72)\r
35         (envelope-from <amthrax@awakening.csail.mit.edu>)\r
36         id 1PVeE7-00024C-MC; Thu, 23 Dec 2010 01:00:35 -0500\r
37 From: Austin Clements <amdragon@MIT.EDU>\r
38 To: notmuch@notmuchmail.org\r
39 Subject: [RFC PATCH 0/2] Custom query parser\r
40 Date: Thu, 23 Dec 2010 01:00:22 -0500\r
41 Message-Id: <1293084024-7893-1-git-send-email-amdragon@mit.edu>\r
42 X-Mailer: git-send-email 1.7.2.3\r
43 X-Brightmail-Tracker: AAAAAA==\r
44 Cc: amdragon@mit.edu\r
45 X-BeenThere: notmuch@notmuchmail.org\r
46 X-Mailman-Version: 2.1.13\r
47 Precedence: list\r
48 List-Id: "Use and development of the notmuch mail system."\r
49         <notmuch.notmuchmail.org>\r
50 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
51         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
52 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
53 List-Post: <mailto:notmuch@notmuchmail.org>\r
54 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
55 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
56         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
57 X-List-Received-Date: Thu, 23 Dec 2010 06:00:48 -0000\r
58 \r
59 Following is a patch series that implements a custom query parser.\r
60 This code is by no means ready for serious review or inclusion in the\r
61 tree, but I wanted to spark some discussion and get feedback while\r
62 it's still molten.\r
63 \r
64 The query parser is basically compatible with Xapian's, but is\r
65 designed to be flexible enough to support (at least) date searches,\r
66 saved queries, folder searches (without a schema change), "from:me",\r
67 and implicit filters (like defaulting to "-tag:spam").  Such features\r
68 are implemented as transformations over an intermediate\r
69 representation, keeping the parser itself as simple as possible.  The\r
70 code already uses transformers for the usual prefixes and the\r
71 type:mail filter, and I have most of the implementation of folder\r
72 searches in another branch.\r
73 \r
74 If you'd like to play with it, it's on the qparser branch at\r
75 http://awakening.csail.mit.edu/git/notmuch.git.  It's not complete,\r
76 but it's close (notably, stemming is missing).\r
77 \r
78 The grammar is approximately compatible with Xapian's query parser.\r
79 To my knowledge, it differs in the following ways:\r
80 \r
81 1) The way this parser separates terms is much simpler and, I believe,\r
82    more predictable.  In Xapian, many things can separate terms, and\r
83    exactly what is context-dependent.  For example, "x/y" is parsed as\r
84    two terms in a phrase, "x#y" is parsed as two separate terms "x"\r
85    and "y", and "x# y" is parsed as two separate terms "x#" and "y".\r
86    This parser instead splits the query into "term phrases", which are\r
87    separated only by whitespace, quote, left paren, or right paren.\r
88    These term phrases are then broken into terms using the same\r
89    Xapian::TermGenerator that tokenizes documents.  If this results in\r
90    multiple terms, they're tied into a phrase in the final query.\r
91    Thus, "x/y" and "x# y" are handled as in Xapian, but "x#y" is\r
92    parsed as a phrase.\r
93 \r
94 2) This parser handles errors differently.  Because queries are\r
95    roughly natural language, I feel they should never fail to parse\r
96    (has Google ever told you that your query contains a syntax\r
97    error?), so this parser tries to do reasonable things in all cases.\r
98    Xapian's parser has a strange approach.  For syntax errors\r
99    involving boolean operators (for example "x AND"), it returns a\r
100    parse error.  For other syntax errors (for example, "x) OR y"),\r
101    Xapian will *retry* the parse from scratch with no parser flags set\r
102    (no operators, parens, or quotes).\r
103 \r
104 3) The handling of NEAR and ADJ is quite different and possibly wrong.\r
105    I didn't realize how subtle these operators were until I'd already\r
106    implemented something completely different from Xapian's logic.\r
107 \r
108 The code is much simpler than Xapian's query parser because it elides\r
109 several features that notmuch doesn't use (such as multi-term\r
110 synonyms), it reuses Xapian's TermGenerator to parse terms (instead of\r
111 copy-pasting and tweaking the code), and because I placed the boundary\r
112 between the lexer and the parser differently.  This parser is under\r
113 1000 lines, while Xapain's is 2000 lines plus a 5000 line parser\r
114 generator.\r
115 \r